2013-02-07 164 views
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会在嵌套块退出后发生?我的理解是,我的街区对自我很有借鉴意义,所以这应该是犹太教。

回答

3

这很好,因为你陈述的原因。

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

+1

这就是为什么我更喜欢'self-> ivar.property',因为我可以看到它保留了'self'。不仅仅是'ivar.property',它实际上通过'self->来扩展。 – Tricertops

+0

如果自己变成零,那么使用self> ivar是不好的,它会导致崩溃。在块中使用它时最好将其定义为属性,并使用__weak self来防止保留周期。 –

0

你是对的。该块在两种情况下保留自己:

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

你的嵌套块很好去两个计数。因此,块将在完成执行后发生dealloc。

另一个值得注意的事情是你的queue也是一个实例变量。我最初的想法是,因为它是一个实例变量,所以self也被保留,直到块完成执行。但是,当我测试它时,实际发生的情况是只保留queue并取消分配self。尽管如此,我无法找到相关文档。

+0

“我最初的想法是,因为它是一个实例变量,所以自我也得到保留,直到块...”不,在我能看到的任何块内没有使用“队列” – newacct