是否有必要使用弱引用自我总是在块内?
我正在混淆使用块内自我,我通过一些苹果的文件,但仍然找不到正确的答案。
有些人总是说在块里面用自己弱的自己,但是有人说在被复制的块里使用弱自我,而不是永恒地使用。
样品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.
注意到在ObjectThatDoesNotRetainBlock
的init
方法中,我们将block
创build为一个ivar,但是当block
超出范围时,我们不保留对它的引用。
在test
方法中,当两个对象超出范围时,请注意objectThatDoesNotRetainBlock
被释放,因为它不是保留周期的一部分。
另一方面, objectThatRetainsBlock
不会被释放,因为它是一个保留周期的一部分。 它保留超出方法调用范围的块。
如果你想要另一个解释,请看这个答案 。