【发布时间】:2010-12-03 12:59:17
【问题描述】:
我正在处理一些代码,这些代码使用各种回调执行一堆异步操作; Snow Leopard 使用积木和 GCD 让这一切变得异常简单。
我从NSBlockOperation 拨打NSTask,如下所示:
[self.queue addOperationWithBlock:^{
NSTask *task = [NSTask new];
NSPipe *newPipe = [NSPipe new];
NSFileHandle *readHandle = [newPipe fileHandleForReading];
NSData *inData = nil;
[task setLaunchPath:path];
[task setArguments:arguments];
[task launch];
while ((inData = [readHandle availableData]) && [inData length]) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// callback
}];
}
[task waitUntilExit];
}];
这种方法非常有效。这就像魔术一样,只要我的回调正确处理并发。
现在,我希望能够合并其中的一些调用;这是在模型对象的“刷新”方法中,可能需要很长时间才能完成。让用户点击刷新按钮不应该占用机器等等。
我可以在这里看到一个实施困境。我可以创建一大堆队列——每种呼叫类型一个——并将它们的并发操作计数设置为 1,然后在需要进行新呼叫时呼叫 -cancelAllOperations。
或者,我可以对当前正在发生的调用进行更多的手动记账,并为每个模型对象管理一个队列(就像我正在做的那样),或者我可以更进一步并使用全局队列。
NSOperationQueue 有多重?创建大量队列是一个糟糕的架构决策吗?有没有更好的方法来合并这些任务?
【问题讨论】:
-
仅供参考,您正在泄露您的 NSTask 和 NSPipe。 +new 等价于 +alloc/-init,这意味着你有责任释放它们......你从来没有做过(在上面的代码中)。 (当然,除非你使用 GC)
-
这是一个仅限雪豹的程序。我当然希望您的全新 Snow-Leopard-only 代码被垃圾收集。 :-D
标签: objective-c cocoa osx-snow-leopard nsoperation