+++
Categories = ["iOS",]
Tags = ["iOS","block",]
date = "2014-06-29T20:36:29+08:00"
title = "有关block"
+++
block发生引用循环
一个对象中强引用了block,在block中又使用了该对象,就会发生循环引用。解决方法就是将该对象使用 __weak
或者 __block
修饰符修饰后在block中使用。
-
id weak weakSelf = self
, 或者weak __typeof(&*self)weakSelf = self
(可以将该方法设置为宏) -
id __block weakSelf = self
;
在block内修改block外部变量
默认情况下,在block中访问的外部变量是复制过去的,即:写操作不对原变量生效。但是你可以加上 __block
来让其写操作生效;
使用系统的某些block api的引用循环问题
系统的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