iOS面试题 关于block 部分

2017-09-15  本文已影响56人  Mrxiaowang

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];  }];


上一篇下一篇

猜你喜欢

热点阅读