【问题标题】:Safe way to access objects of an NSOperation from the Main Thread?从主线程访问 NSOperation 对象的安全方法?
【发布时间】:2011-06-05 11:57:12
【问题描述】:

NSOperation 在主线程中有一个委托,它会在 NSOperation 运行时被调用一些事件。

Delegate 然后访问 NSOperation 的属性以获取详细信息。

我担心这种边缘情况:如果 NSOperation 在调用委托后一纳秒被队列释放怎么办?我担心突然所有对象都可能由于 NSOperation 的 -dealloc 中的 -release 而消失,然后我在主线程上得到一个 EXC_BAD_ACCESS。

您如何防止这种情况发生?我想过在后台运行的 NSOperation 中做这样的事情:

[(NSObject*)self.delegate performSelectorOnMainThread:@selector(operationUpdatedStatus:) withObject:[[self retain] autorelease] waitUntilDone:NO];

但我认为这是无稽之谈,因为自动释放池也会立即耗尽,因为它是 NSOperation 本地的。

所以可以肯定的是,我必须像这样在主线程的委托方法中保留 NSOperation 吗?

- (void)operationUpdatedStatus:(NSOperation*)op {
    [op retain]; // now we're safe to use it

    NSMutableArray *errorMessages = op.errors;
    for (NSString *errorMessage in errorMessages) {
        // lots of code
    }

    [op release];
}

还是保证 NSOperation 对象在主线程的运行循环结束之前不会被杀死?

【问题讨论】:

    标签: objective-c ios memory-management concurrency nsoperation


    【解决方案1】:

    根据the NSObject docsperformSelectorOnMainThread保留了选择器目标以及通过withObject传递的对象;在要执行的选择器完成之前,两者都不会被释放。所以你的[[self retain] autorelease]有多余的。

    【讨论】:

      【解决方案2】:

      我现在正在 NSOperation 中进行非常相似的编码。我将操作添加到队列中,但由于我知道操作很快就会消失,因此我通过委托中的对象将任何需要的值传递回调用类。大多数时候,如果它超过 1 个对象,我会使用 NSDictionary 来执行此操作。我从来没有遇到过使用这种方法释放实例的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-19
        • 2018-06-24
        • 1970-01-01
        相关资源
        最近更新 更多