2

我正在努力寻找一种在 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 并将其附加到顶部,而最后一个操作应该删除它。

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

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

谢谢

4

3 回答 3

1

怎么写

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

然后在'reloadDataSource'方法中调用你的主线程

[self performSelectorInMainThread:@selector(spinnerOn:) withObject:NO];
于 2010-10-16T15:56:13.913 回答
0

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

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

我很想知道这是否会有所作为。我的怀疑是,如果您从备用线程调用 UI 任务,这些任务会排队并最终可能在稍后的未定义时间在主线程上同时发生。

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

[self.queue setMaxConcurrentOperationCount:1];

让我知道这是否有帮助。

于 2010-10-18T15:57:47.127 回答
0

是否必须使用 NSOperation?如果不是,那么我猜你正在选择解决简单问题的艰难方法,使用 NSConnection 的委托(或类似的东西,因为我不确定你的 reloadDataSource 做了什么)来启动和停止微调器,然后你就是完毕。

于 2010-10-16T14:47:22.393 回答