5

假设我有一个类(非 ARC 环境):

@interface SomeObject : NSObject {
    UILabel *someLabel;
    dispatch_queue_t queue;
}
- (void)doAsyncStuff;
- (void)doAnimation;
@end

@implementation SomeObject

- (id)init {
    self = [super init];
    if (self) {
        someLabel = [[UILabel alloc] init];
        someLabel.text = @"Just inited";
        queue = dispatch_queue_create("com.me.myqueue", DISPATCH_QUEUE_SERIAL);
    }
    return self;
}

- (void)doAsyncStuff {
    dispatch_async(queue, ^{
        ...
        // Do some stuff on the current thread, might take a while
        ...
        dispatch_async(dispatch_get_main_queue(), ^{
            someLabel.text = [text stringByAppendingString:@" in block"];
            [self doAnimation];
        }
    }
}

- (void)doAnimation {
    ...
    // Does some animation in the UI
    ...
}

- (void)dealloc {
    if (queue) {
        dispatch_release(queue);
    }
    [someLabel release];
    [super dealloc];
}

如果我的块被启动,然后所有其他持有对该对象实例的引用的东西都释放它,我是否保证不会调用 dealloc,因为嵌套块引用了一个实例变量(和 self)——那个 dealloc嵌套块退出后会发生吗?我的理解是我的块对自我有很强的参考,所以这应该是犹太洁食。

4

2 回答 2

3

这很好,因为你所说的原因。

需要注意的重要一点是,如果类(由 表示self)以任何方式保留了块,您将创建一个保留循环。因为您在线定义它,并将其传递给dispatch_async,所以您应该没问题。

于 2013-02-07T18:14:48.960 回答
0

你是绝对正确的。该块在两种情况下保留自我:

  1. 您在块内使用 self 。
  2. 您可以直接在块内访问实例变量。

您的嵌套块在这两个方面都很好。因此,dealloc 将在块执行完毕后发生。

另一个需要注意的有趣的事情是 yourqueue也是一个实例变量。我最初的想法是,因为它是一个实例变量,所以self也会保留到块执行完毕。然而,当我测试它时实际发生的只是queue被保留self并被释放。不过,我无法找到这方面的文档。

于 2013-02-07T20:34:12.950 回答