2013-10-31 155 views
0

問題:我是否正確使用此塊?沒有泄漏或保留週期?我是否正確使用此塊?

問題1.5:這是一種很好的風格,還是我應該做一個內聯塊?

typedef void(^completionBlock)(void); 

... 

-(completionBlock)completionBlock{ 
    return ^{ 
     [[NSNotificationCenter defaultCenter] postNotificationName:kFetchNewTopicsAndReloadTableData object:nil]; 
    }; 
} 

.. 

-(void)refresh 
{ 
    [self dismissViewControllerAnimated:YES completion:[self completionBlock]]; 
} 
+4

除非重複使用塊,否則我會發現內聯塊的風格更好。 – sbooth

回答

1

該塊沒有引用self,通過引用實例變量顯式或隱式引用。所以它不會保留self。所有它將顯而易見保留的是元類NSNotificationCenter,我所假設的是一個全局常量,kFetchNewTopicsAndReloadTableData,既不導致任何其他的保留。

所以肯定沒有保留週期,因爲該塊不處理任何瞬態對象。

即使它確實保留self,也沒有問題。比較和類似對比:

@implementation SomeClass 
{ 
    block_t someHandler; 
} 

... 
    someHandler = [^{ [self doSomething]; } copy]; 

,創建一個保留週期,因爲該塊,然後通過selfself保留由塊保留。你稍後可能會打破這個循環,但僅僅使用一個弱引用而不是首先創建循環會更安全。

至於返回塊的方式是否爲壞形式:從技術上說是的,理由是你應該有copy這樣才能返回它。如果要在塊聲明範圍之外使用塊,則塊應該被複制。如果它是內聯的,則不需要複製它,因爲這將是dismissViewControllerAnimated:...的責任。這個塊會因爲沒有捕獲除了全局狀態以外的任何東西而逃脫,但這也意味着該副本本質上是免費的,所以它不值得做例外。

至於你更可能問的是什麼,它可以說是過度複雜的語法來添加一個額外的方法來包裝塊的聲明,但如果你需要多次相同的塊,那麼因式分解的普通規則就會適用。

+0

我只想補充一點,在返回它之前複製一個塊是由ARC自動管理的,所以,除非MRC就位,否則明確的「複製」調用將是多餘的。 –