目标c - 阻止保留周期

Mar*_*rio 2 iphone objective-c ios objective-c-blocks

我有一个块保留周期问题,
假设我有以下3种方法,都在一个类中.

- (void)foo1WithBlock:(void (^)(BOOL success))completion
   // do something...
   completion(YES)
}  

- (void)foo2 {
   // do something...
}  

- (void)foo3 {
   [self foo1WithBlock:^(BOOL success) {
       [self foo2];
   }]; 
}
Run Code Online (Sandbox Code Playgroud)

foo3会创建一个保留周期吗?

Cou*_*per 9

不,没有保留周期.

但是,self将被捕获.这意味着,self将被导入复合语句的词法范围(由块执行的语句).这涉及制作"外部"变量的副本,该变量self创建块的变量self.

可以复制释放块.一个block_copy操作将"移动"拍摄变量到堆上.它们存在于那里,直到块通过block_release操作被破坏.编译器/运行时提供内部函数来复制和释放块,并在需要时执行它们.例如,如果通过块异步执行dispatch_async()块,则必须先复制,然后在块完成时再次释放.这些block_copyblock_release操作由编译器插入并由运行时执行,因此不必担心.

如果块将被复制,因为效果self将被保留,并在块被释放时再次释放 - 这在块完成时发生.

实际上,这可以保证self块内和块的生命周期内是有效的(也就是说,它不会被释放),无论是同步调用还是异步调用.当块已异步执行时,块已被复制,因此self已被保留.并且self只有在块结束后才会再次释放.这也意味着,块"将"延长self块直到完成之后的寿命.