1、使用block时什么情况会发生引用循环,如何解决?
答:一个对象中强引用了block,在block中又强引用了该对象,就会发射循环引用。
解决方法是将该对象使用__weak或者__block修饰符修饰之后再在block中使用。
2、在block内如何修改block外部变量?
答:认情况下,在block中访问的外部变量是复制过去的,即:写操作不对原变量生效。但是你可以加上 __block
来让其写操作生效,示例代码如下:
__block int a = 0;
void (^foo)(void) = ^{
a = 1;
};
foo(); //这里,a的值被修改为1
3、使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?
答:系统的某些block api中,UIView的block版本写动画时不需要考虑,但也有一些api 需要考虑:
所谓“引用循环”是指双向的强引用,所以那些“单向的强引用”(block 强引用 self )没有问题,比如这些:
[UIViewanimateWithDuration:durationanimations:^{ [self.superviewlayoutIfNeeded]; }];
[[NSOperationQueuemainQueue]addOperationWithBlock:^{ self.someProperty= xyz; }];
[[NSNotificationCenterdefaultCenter]addObserverForName:@"someNotification"object:nilqueue:[NSOperationQueuemainQueue]usingBlock:^(NSNotification* notification) { self.someProperty= xyz; }];
这些情况不需要考虑“引用循环”。
但如果你使用一些参数中可能含有 ivar 的系统 api ,如 GCD 、NSNotificationCenter就要小心一点:比如GCD 内部如果引用了 self,而且 GCD 的其他参数是 ivar,则要考虑到循环引用:
__weak__typeof__(self) weakSelf = self;dispatch_group_async(_operationsGroup, _operationsQueue, ^{__typeof__(self) strongSelf = weakSelf;[strongSelfdoSomething];[strongSelfdoSomethingElse];} );
类似的:
__weak__typeof__(self) weakSelf = self; _observer = [[NSNotificationCenterdefaultCenter]addObserverForName:@"testKey"object:nilqueue:nilusingBlock:^(NSNotification*note) {__typeof__(self) strongSelf = weakSelf; [strongSelfdismissModalViewControllerAnimated:YES]; }];
网友评论