6

我正在使用一些代码,这些代码使用各种回调执行一堆异步操作;Snow Leopard 使用积木和 GCD 让这一切变得异常简单。

我是这样打电话NSTaskNSBlockOperation

[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?创建大量队列是一个糟糕的架构决策吗?有没有更好的方法来合并这些任务?

4

3 回答 3

8

如果您担心性能,请不要猜测:测量然后修复您发现的任何瓶颈。添加队列很简单;试一试,看看 Instruments 告诉你什么对性能的影响。

创建多个队列的主要原因是如果您有某种原因想要启动和停止它们。如果您只想获得 libdispatch 的好处,您可以通过将操作添加到主队列来实现。

于 2009-10-03T08:07:18.827 回答
1

您可以将多个块添加到将同时执行的 NSBlockOperation 并且可以通过取消包含操作来取消。只要您的个人任务不必序列化,这可能会起作用。

于 2009-10-03T14:40:17.557 回答
0

只需使用任意数量的操作队列即可。它们用于分隔程序的逻辑部分。只要您不每秒分配数百个队列,我认为您不应该太关心性能。

于 2009-10-03T08:32:20.757 回答