2013-02-07 200 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