OC语言(七)Block复习

看下面一道Block的面试题:

int i = 10;
void(^myBlock)() = ^{
NSLog(@"%d",i);
};
i = 100;
myBlock();

经过这个过程后,输出的i应该是10而不是100,在定义block时会将block前面的局部变量进行拷贝,后续的变量改变不会影响block内部的拷贝变量值,如果要操作block中变量的值,应该加上__block关键字。

另外一道:

Tip:如果在block中使用了self,block会对self强引用。

@property (nonatomic, strong) NSMutableArray *myBlocks;

int(^sum)(int,int) = ^(int x, int y){
return [self sum:x y:y];
}
[self.myBlocks addObject:sum];

注意到self对myBlocks是强引用,如果把sum加入到myBlocks数组中,myBlocks数组又会有强指针指向sum,由于sum这个block需要调用self的方法,因此sum对self是强引用,因此构成了循环引用,无法释放。

第三道:

如果self对象持有操作对象(例如类直接有block),而操作对象(如block)又直接访问了self,则block会对self构成强引用,self又对block强引用,会造成循环引用。

单纯在操作对象(如block)中操作self不会造成循环引用。

例如使用线程创建block,由于非主线程默认没有消息循环(Run Loop),因此线程销毁时block也会销毁,block为线程所有,不是self所有,不会造成循环引用。

@interface DemoObj ()

@property (nonatomic, strong) NSOperationQueue *queue;

@end

@implementation DemoObj

- (instancetype)init{

    if(self = [super init]){
self.queue = [[NSOperationQueue alloc] init];
} return self; }
- (void)dealloc{ NSLog(@"dealloc successfully"); } - (void)demoOp:(id)obj{ NSLog(@"%@ %@",[NSThread currentThread],obj); } - (void)demoBlockOp{
[self.queue addOperationWithBlock:^{
[self demoOp:@"hello"];
}];
}

这种情况下,self对queue强引用,queue对block强引用,虽然block对self也有强引用,但是线程消失时block会销毁,也就不存在引用环了,因此self只有直接拥有block时才会造成循环引用。

Tip:在这种情况下,不能使用self的弱引用(__weak Demoobj *weakself = self),这样对象会在创建时的强指针销毁时被销毁,也就是说block指向的self类不能保证其存在,故block会无法调用self,注意不能使用弱引用!!!

上一篇:python基础===map和zip的用法


下一篇:webserver nginx / https / upstream