【问题标题】:How lightweight is NSOperationQueue on Snow Leopard?Snow Leopard 上的 NSOperationQueue 有多轻量级?
【发布时间】: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


【解决方案1】:

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

创建多个队列的主要原因是如果您有一些理由想要启动和停止它们。如果您只是想获得 libdispatch 的好处,您只需将操作添加到主队列即可。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    【解决方案3】:

    只要你喜欢使用尽可能多的操作队列。它们用于分隔程序的逻辑部分。只要您不每秒分配数百个队列,我认为您不必太在意性能。

    【讨论】:

    • 网站?这与网站有什么关系?
    • 谢谢,现在还早。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 1970-01-01
    相关资源
    最近更新 更多