繁体   English   中英

如果一个强属性具有一个涉及自我的障碍,那是一个保留周期吗?

[英]If a strong property has a block that refers to self, is that a retain cycle?

例如:

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

其中contentWrapperViewself的强属性,并且假定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的术语来说,这意味着您强烈拥有的任何变量都不能反过来强烈拥有 这通常是通过声明一个属性需要weakunsafe_unretained ,未unsafe_unretainedassign父属性来解决的。 这会因块而变得复杂,而块通常像闭包一样捕获对它们中每个变量的const或保留引用(显然, __block限定符会使其更加复杂)。

与其从块的角度看待这个问题,我将尝试将其抽象为带有两个类的示例,这对于使用OO lang的人来说通常更容易实现:

假设我有MyImportantObject类,该类需要与另一个MyWorkerClass类做一些工作。 通常,我们通常需要对MyWorkerClass的强引用,因为也许我们希望它能坚持下去,以便我们以后可以做更多的工作,或者一遍又一遍地调用相同的worker方法:

@interface MyImportantObject : NSObject 

@property (nonatomic, strong) MyWorkerClass *workerObj;

@end

反过来,我们的工作人员需要稳定引用其需要工作的所有MyImportantObject的属性(否则它将无法工作 !)。 因此,引用self块会执行​​什么操作,而不是对每个变量采用const或保留引用,而是对其父对象保留引用!

@interface MyWorkerClass : NSObject 

@property (nonatomic, strong) MyImportantObject *workerObj;

@end

这意味着如果您尝试使用MyImportantObject的辅助对象,它们将相互保留,并且不会被正确释放! 巨大的不。

通过将self转移到__weak (或MRC下的__block )指针中,我们得到的引用看起来像这样:

@interface MyWorkerClass : NSObject 

@property (nonatomic, weak) MyImportantObject *workerObj;

@end

不再有保留周期,每个人都高兴,当父母沿着恐龙的路走时,每个人都被适当地释放。

但是还有一个难题:我们如何处理weak引用? 毕竟,我们说好ol编译恶有恶报和猛拉self从你下了一个快速-release 由于归零弱指针,您现在在块中有一个运行amok的nil指针。 这可能导致它实际上什么也没做,而您坐在那里挠头想知道为什么。 这导致了我称之为弱劲舞的发明。

J_mcnally的示例缺少舞蹈中的关键一步,即自我指针的“重新增强”。 但是,在我们为避免保留周期而费尽心思之后,为什么还要这样做呢? 这是因为我们的X的强副本没有被块保留,而是被块的scope保留了。 用英语来说,这意味着我们强大的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.
}]];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM