NSOperation同步问题

时间:2010-10-16 11:09:57

标签: iphone objective-c nsoperation

我正在努力寻找一种在iPhone应用上同步操作的方法。 我有三个主要的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并将其附加在顶部,而最后一个操作应该将其删除。

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

我知道图形方面的更改发生在主线程上。所以我问我怎么能修改代码来做它应该做的事情。这是:创建微调器,加载数据和删除微调器?有没有通用的方法来分离图形操作和数据操作?例如,创建两个不同的操作。

感谢

3 个答案:

答案 0 :(得分:1)

怎么写

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

然后使用

在'reload DataSource'方法中回调主线程
[self performSelectorInMainThread:@selector(spinnerOn:) withObject:NO];

答案 1 :(得分:0)

使用NSOperation是否必须?如果没有,那么我猜你正在选择解决这个简单问题的难题,使用NSConnection的委托(或类似的东西,我不知道你的reloadDataSource做了什么)来启动和停止微调器,然后你就是完成。

答案 2 :(得分:0)

在你的spinnerOn:方法中,你可以尝试添加一些逻辑来确保在主线程上进行操作吗?

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

我很想知道这是否有所作为。我怀疑的是,如果你从一个备用线程调用一个UI任务,那些就会排队等待,并且最终可能会在主线程上的一个未定义的时间内一次性发生。

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

  

[self.queue setMaxConcurrentOperationCount:1];

让我知道这是否有用。