2010-10-16 74 views
2

我很努力地找到一种方法来同步iPhone应用程序的操作。 我有三个主要的NSOperation。NSOperation同步问题

NSInvocationOperation *showSpinner = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(spinnerOn:) object:YES]; 
    NSInvocationOperation *reloadDatasource = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(reloadDatasource) object:nil]; 
    NSInvocationOperation *hideSpinner = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(spinnerOn:) object:NO]; 
    // Add dependency 
    [reloadDatasource addDependency:showSpinner]; 
    [hideSpinner addDependency:reloadDatasource]; 

    [self.queue addOperation:showSpinner]; 
    [self.queue addOperation:reloadDatasource]; 
    [self.queue addOperation:hideSpinner]; 

我可以看到三个操作顺序正确启动。然而,正如你可以想象的那样,第一个操作创建一个UIView并将其附加在顶部,而最后一个应该删除它。

这种情况发生在图形上说操作在屏幕上立即发生。所以我可以看到表格已经加载,而微调屏幕上,或其他奇怪的不同步的东西。

我明白图形端的变化发生在主线程上。所以我问我该如何修改代码来完成它应该做的事情。这是:创建微调,加载数据,并删除微调?有没有一种常见的方法来分离图形操作和数据操作?例如创建两个不同的操作。

谢谢

+0

微调控制器最终会被移除还是只是保持旋转? hideSpinner操作是否被调用? – twerdster 2010-10-16 13:18:30

+0

从你的描述看来,你实际上需要同步操作......我看到这个错误吗?我的意思是,你可能想要保持reloadDatasource异步,以保持你的Ms和Cs不受你的V(因为它),但是GUI的东西就像直接的因果关系,是的? – fish2000 2010-10-16 14:21:48

+0

是的,都应该同步发生,包括Views的管理。我只想显示带有消息的视图,如“等待我加载数据”,然后在后台启动reloadData中,一旦完成,我想要删除微调视图。 – Leonardo 2010-10-16 15:00:28

回答

0

是否必须使用NSOperation?如果不是,那么我想你正在选择解决简单问题的难题,使用NSConnection的委托(或者类似于我不确定你的reloadDataSource做什么)来启动和停止微调,然后你是'完成。

1

如何写

[self spinnerOn:YES]; 
[self performSelectorInBackground:@selector(reloadDatasource) withObject:nil]; 

,然后拨打电话回在“reloadDataSource”的方法你的主线程与

[self performSelectorInMainThread:@selector(spinnerOn:) withObject:NO]; 
+0

这似乎会导致相同的问题,对UI的更改发生与工作流相关的不同步。 – Leonardo 2010-10-16 16:32:13

+0

请您详细说明它是如何“不同步”的? – tia 2010-10-16 16:43:01

+0

我不得不改变语法,因为它是错误的,还有一些其他的改变,使它的应用程序的方法,使其工作。我的意思是'不同步'是显示微调,然后重新加载数据,然后最后删除微调。但是所有的任务应该同步。一个接一个地。我一直认为NSQueue是最好的同步方式。 – Leonardo 2010-10-18 07:56:06

0

在你spinnerOn:方法,你可以尝试添加一点逻辑确保操作发生在主线程上?

if (![NSThread isMainThread]) { 
    [self performSelectorOnMainThread:@selector(spinnerOn:) withObject:anObject waitUntilDone:NO]; 
    return; 
} 

我很好奇,看看是否有差别。我的怀疑是,如果你从一个备用线程调用一个UI任务,那么这些任务就会排队等候,最终可能会在主线程中稍后未定义的时间内一次性发生。

另一个尝试的选择是让您的操作队列为serial队列。我的意思是一次只能执行一项任务。然后你可以忘记你的依赖关系,因为它总是会按照你添加它们的顺序执行任务。您可以尝试设置它:

[self.queue setMaxConcurrentOperationCount:1];

让我知道这是否有帮助。