如果一个强大的财产有一个指向自我的块,那么这是一个保留周期吗?

例如:

[self.contentWrapperView addGestureRecognizer: [UITapGestureRecognizer recognizerWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) { if (self.customEditing) { [self setEditingMode:NO Animated:YES]; } }]]; 

其中contentWrapperView是一个强大的self属性,并假设contentWrapperView具有强大的识别器块引用。 在块中使用self将导致保留周期? 这是我不明白的唯一部分。

是的,这将导致保留周期。

你的护理的解决方法是

 __weak id weakSelf = self; [self.contentWrapperView addGestureRecognizer:[UITapGestureRecognizer recognizerWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) { if ([weakSelf customEditing]) { [weakSelf setEditingMode:NO Animated:YES]; } }]]; 

根据实际情况考虑一个保留周期:保留自己的对象。

在Cocoa和Cocoa-Touch的术语中,这意味着任何你拥有的variables都不能强有力地拥有 。 这通常是通过声明一个需要拥有它的父weakunsafe_unretainedassign的属性来获得的。 这会因块而变得复杂,块作为闭包,通常会捕获常量或保留对其中每个variables的引用(显然,通过__block限定符更加复杂)。

我不是从块的angular度来看待这个问题,而是试图将它抽象成一个有两个类的例子,这对于一个OO语言来说通常更容易理解:

比方说,我有MyImportantObject类,它需要与另一个类MyWorkerClass 。 我们通常需要对MyWorkerClass的强引用,因为我们可能希望它继续存在,所以稍后我们可以做更多的工作,或者继续反复调用同一个worker方法:

 @interface MyImportantObject : NSObject @property (nonatomic, strong) MyWorkerClass *workerObj; @end 

反过来,我们的工作人员需要一个稳定的引用来处理MyImportantObject的所有属性(否则它不能工作 !)。 那么,什么阻止引用self做,而不是采取一个常量或保留对每个variables的引用,他们采取保留引用他们的父母!

 @interface MyWorkerClass : NSObject @property (nonatomic, strong) MyImportantObject *workerObj; @end 

这意味着如果你试图使用MyImportantObject的工作对象,他们会保留对方,并且都不会被正确释放! 巨大的不,不。

通过将self分stream到__weak (或MRC下的__block )指针,我们可以得到如下所示的引用:

 @interface MyWorkerClass : NSObject @property (nonatomic, weak) MyImportantObject *workerObj; @end 

没有更多的保留周期,每个人都快乐,当父母走上恐龙之路的时候,每个人都会被正确地释放。

但是还有一个难题:我们对weak参考文献做了什么? 毕竟,让我们说好的编译器出现在你的-release ,快速地-release 。 由于这个调零的弱指针,你现在有一个零指针在你的区块里乱跑。 这可能会导致它从字面上什么也不做,而你坐在那里,想你为什么挠头。 这导致了我所说的弱小舞蹈的发明。

J_mcnally的例子是在舞蹈中失去了一个关键的步骤,你的自我指针“重新强化”。 但是,为了避免保留周期,我们为什么要这么做呢? 这是因为我们强大的X副本没有被块保留,而是被块的范围所保留。 在英语中,这意味着我们强大的self只有在块的末端达到时才会释放,这样不仅保证了一个安全的存储周期,而且也不会从我们下面被释放。 一个适当的修复看起来像这样:

 __weak id weakSelf = self; [self.contentWrapperView addGestureRecognizer:[UITapGestureRecognizer recognizerWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) { id strongSelf = weakSelf; if ([strongSelf customEditing]) { [strongSelf setEditingMode:NO Animated:YES]; } //Do some other stuff before strongSelf passes out of scope. }]];