2011-12-14 55 views
4

使用Xcode 4.2和ARC,我寫了下面的代碼,然後才明白需要如何將塊從堆棧複製到堆。塊,堆棧和堆

-(void) downloadWithBlock:(void (^)(void))callbackBlock; 
{ 
    // start the data download in the background... 
    NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     // synchronous download code 
    }]; 
    [backgroundOperationQueue addOperation:backgroundOperation]; 
    NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     callbackBlock(); 
    }]; 
    [foregroundOperation addDependency:backgroundOperation]; 
    [[NSOperationQueue mainQueue] addOperation:foregroundOperation];  
} 

該代碼有效,但我不相信它,因爲我不理解它。在另一部分代碼中,我遇到了應用程序崩潰,同時調用存儲在ivars中的塊而不使用-copy。這使我懷疑是否這部分代碼應該這樣被改寫:

-(void) downloadWithBlock:(void (^)(void))callbackBlock; 
{ 
    void(^heapBlock)(void) = [callbackBlock copy];  
    // start the data download in the background... 
    NSOperation *backgroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     // synchronous download code 
    }]; 
    [backgroundOperationQueue addOperation:backgroundOperation]; 
    NSOperation *foregroundOperation = [NSBlockOperation blockOperationWithBlock:^{ 
     heapBlock(); 
    }]; 
    [foregroundOperation addDependency:backgroundOperation]; 
    [[NSOperationQueue mainQueue] addOperation:foregroundOperation];  
} 

我這裏只關心的是更好地瞭解塊的指針是如何工作的。這些代碼段中的任何一個都可接受?在另一個塊中調用塊是否觸發編譯器插入一個隱藏的Block_copy操作?

回答

1

不僅僅是調用一個塊內的塊,而是直接引用一個塊會引起一個副本。包括將它作爲參數傳遞給別的東西。塊中的ObjC類型也一樣(除了它是簡單的保留,不是它們的副本)。

+0

謝謝,這是有道理的。與其他ObjC類型的類比有所幫助,因爲我明白塊會觸發ARC編譯器保留塊引用的任何標準ObjC對象。 –

+0

即使沒有ARC,也會發生阻塞,這很奇怪,但非常有用。同樣可以理解的是,塊至少在OS發佈週期之前早於ARC。 – Stripes