一个对象中强引用了block,在block中又使用了该对象,就会发生循环引用。解决方法就是将该对象使用 __weak
或者 __block
修饰符修饰后在block中使用。
id weak weakSelf = self
, 或者 weak __typeof(&*self)weakSelf = self
(可以将该方法设置为宏)id __block weakSelf = self
;默认情况下,在block中访问的外部变量是复制过去的,即:写操作不对原变量生效。但是你可以加上 __block
来让其写操作生效;
系统的block api中,UIView的block版本写动画时不需要考虑。
所谓“引用循环”是指双向的强引用,所以那些“单向的强引用”(block强引用 self)没有问题。
[UIView animateWithDuration:duration animations:^{ [self.superview layoutIfNeeded]; }];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.property = foo; }];
[[NSNotificationCenter defaultCenter] addObserverForName:@"cl_Notification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * notification) {
self.property = boo; }];
但是如果你使用了一些参数中可能含有ivar的体统api,如GCD、 NSNotificationCenter就要小心。
__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
__typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
} );
例如:
__weak __typeof__(self) weakSelf = self;
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"testKey"
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
__typeof__(self) strongSelf = weakSelf;
[strongSelf dismissModalViewControllerAnimated:YES];
}];
self–> _observer –> block –> self