2013-10-31 159 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就位,否则明确的“复制”调用将是多余的。 –