是否有必要使用弱引用自我总是在块内?

我正在混淆使用块内自我,我通过一些苹果的文件,但仍然找不到正确的答案。

有些人总是说在块里面用自己弱的自己,但是有人说在被复制的块里使用弱自我,而不是永恒地使用。

样品1:

self.handler = ^(id response, NSError *error) { self.newresponse = response; //use weak self here }; 

样品2:

使用虚弱的自我;

 __weak myViewController *weakSelf = self; [UIView animateWithDuration:interval delay:0.0 options:curve animations:^ { [weakSelf.view.superview setTransform:CGAffineTransformMakeTranslation(0, -106)]; //in above is it use of weak is neassary } completion:^(BOOL finished) { }]; 

没有虚弱的自我;

 __weak myViewController *weakSelf = self; [UIView animateWithDuration:interval delay:0.0 options:curve animations:^ { [myViewController.view.superview setTransform:CGAffineTransformMakeTranslation(0, -106)]; } completion:^(BOOL finished) { }]; 

在上面的样本中,哪个是正确的? **我正在使用ARC

你应该只使用一个弱的self引用,如果self将坚持一个块的引用。

在你的例子中,你没有保持自己的块的引用,你只是使用UIView animateWithDuration:UIView animateWithDuration:块,因此不需要使用__weak myViewController *weakSelf = self;

这是为什么? 因为块将使用块从类中保留对其使用的任何variables的强引用。 这包括self 。 现在,如果类实例本身保持对块的强引用,并且该块保持对类实例的强引用,则会有一个保留周期,这将导致内存泄漏。

下面是一些演示@ WDUK答案的代码:

 typedef void (^SimpleBlock)(); @interface ObjectThatRetainsBlock : NSObject @property(nonatomic, strong) SimpleBlock block; @end @implementation ObjectThatRetainsBlock - (instancetype)init { self = [super init]; if (self) { self.block = ^{ NSLog(@"Running block in %@", self); }; self.block(); } return self; } - (void)dealloc { NSLog(@"ObjectThatRetainsBlock is deallocated."); } @end @interface ObjectThatDoesNotRetainBlock : NSObject @end @implementation ObjectThatDoesNotRetainBlock - (instancetype)init { self = [super init]; if (self) { SimpleBlock block = ^{ NSLog(@"Running block in %@", self); }; block(); } return self; } - (void)dealloc { NSLog(@"ObjectThatDoesNotRetainBlock is deallocated."); } @end - (void)test { ObjectThatRetainsBlock *objectThatRetainsBlock = [[ObjectThatRetainsBlock alloc] init]; ObjectThatDoesNotRetainBlock *objectThatDoesNotRetainBlock = [[ObjectThatDoesNotRetainBlock alloc] init]; } 

test方法打印:

 Running block in <ObjectThatRetainsBlock: 0x7f95f3335e50> Running block in <ObjectThatDoesNotRetainBlock: 0x7f95f3335c50> ObjectThatDoesNotRetainBlock is deallocated. 

注意到在ObjectThatDoesNotRetainBlockinit方法中,我们将block创build为一个ivar,但是当block超出范围时,我们不保留对它的引用。

test方法中,当两个对象超出范围时,请注意objectThatDoesNotRetainBlock被释放,因为它不是保留周期的一部分。

另一方面, objectThatRetainsBlock不会被释放,因为它是一个保留周期的一部分。 它保留超出方法调用范围的块。

如果你想要另一个解释,请看这个答案 。