4

我正在编写一个应用程序,它使用 ASI HTTP 定期从 Web 服务器获取数据,然后处理该数据以在 UI 上显示与用户相关的内容。从单个服务器上的不同请求中检索数据。数据本身需要按特定顺序处理。其中一个数据块比其他数据块大得多。

为了在处理数据时不锁定 UI,我尝试使用NSOperationQueue来在不同线程上运行数据处理。这在大约 90% 的情况下都可以正常工作。然而,在剩下的 10% 的时间里,最大的数据块正在主线程上处理,这会导致 UI 阻塞 1-2 秒。该应用程序在不同的选项卡中包含两个 MKMapView。当两个 MKMapViews 选项卡都加载时,在主线程上处理最大数据块的时间百分比增加了 50% 以上(这似乎表明当有更多并发活动时会发生这种情况)。

有没有办法防止NSOperationQueue在主线程上运行代码?

我尝试使用NSOperationQueue –setMaxConcurrentOperationCount:, 增加和减少它,但在这个问题上没有真正的变化。

这是启动定期刷新的代码:

- (void)refreshAll{    

    // Create Operations
    ServerRefreshOperation * smallDataProcessor1Op = [[ServerRefreshOperation alloc] initWithDelegate:_smallDataProcessor1];
    ServerRefreshOperation * smallDataProcessor2Op = [[ServerRefreshOperation alloc] initWithDelegate:_smallDataProcessor2];
    ServerRefreshOperation * smallDataProcessor3Op = [[ServerRefreshOperation alloc] initWithDelegate:_smallDataProcessor3];
    ServerRefreshOperation * smallDataProcessor4Op = [[ServerRefreshOperation alloc] initWithDelegate:_smallDataProcessor4];
    ServerRefreshOperation * smallDataProcessor5Op = [[ServerRefreshOperation alloc] initWithDelegate:_smallDataProcessor5];
    ServerRefreshOperation * hugeDataProcessorOp = [[ServerRefreshOperation alloc] initWithDelegate:_hugeDataProcessor];

    // Create dependency graph (for response processing)
    [HugeDataProcessorOp addDependency:smallDataProcessor4Op.operation];
    [smallDataProcessor5Op addDependency:smallDataProcessor4Op.operation];
    [smallDataProcessor4Op addDependency:smallDataProcessor3Op.operation];
    [smallDataProcessor4Op addDependency:smallDataProcessor2Op.operation];
    [smallDataProcessor4Op addDependency:smallDataProcessor1Op.operation];

    // Start be sending all requests to server (startAsynchronous directly calls the ASIHTTPRequest startAsynchronous method)
    [smallDataProcessor1Op startAsynchronous];
    [smallDataProcessor2Op startAsynchronous];
    [smallDataProcessor3Op startAsynchronous];
    [smallDataProcessor4Op startAsynchronous];
    [smallDataProcessor5Op startAsynchronous];
    [hugeDataProcessorOp startAsynchronous];
}

这是设置启动数据处理的 ASI HTTP 完成块的代码:

[_request setCompletionBlock:^{
    [self.delegate setResponseString:_request.responseString];
    [[MyModel queue] addOperation:operation]; // operation is a NSInvocationOperation that calls the delegate parse method
}];

我在入口点的所有 NSInvocationOperation Invoked 方法中添加了这段代码:

if([NSThread isMainThread]){
    NSLog(@"****************************Running <operation x> on Main thread");
}

每次 UI 冻结时都会打印该行。这表明整个操作是在主线程上运行的。实际上总是hugeDataProcessorOp在主线程上运行。我认为这是因为它总是最后从服务器接收到它的答案的操作。

4

2 回答 2

4

在对我自己的代码进行大量调查之后,我可以确认这是一个编码错误。

剩下的旧调用没有通过 NSInvocationOperation 而是调用 NSInvocationOperation 应该直接调用的选择器(因此不使用 concurrent NSOperationQueue.

这意味着NSOperationQueue不使用主线程(除非它是由 检索的+mainQueue)。

于 2012-05-15T15:08:42.373 回答
0

覆盖isConcurrent您的 NSOperation 并返回YES。根据文档,这将导致您的 NSOperation 异步运行。

于 2012-05-14T16:44:15.363 回答