美文网首页项目经验iOS 面试iOS-block
block 中使用__weak 和__strong修饰符的问题

block 中使用__weak 和__strong修饰符的问题

作者: __骨头__ | 来源:发表于2015-11-15 17:49 被阅读5296次

问题阐述

在ARC环境下,我们常常会使用__weak 的修饰符来修饰一个变量,防止其在block中被循环引用,但是有些特殊情况下,我们在block中又使用__strong 来修饰这个在block外刚刚用__weak修饰的变量,为什么会有这样奇怪的写法呢?

后来上网查资料,给的解释就是下面的这段话:

    在block中调用self会引起循环引用,但是在block中需要对weakSelf进行
strong,保证代码在执行到block中,self不会被释放,当block执行完后,
会自动释放该strongSelf;

对于程序员来说,文字说明要有,编码就更少不了了;下面是我对上面的话转译成的代码;

第一步:我们自定义一个类,在该类dealloc方法中加一行打印语句;

@interface SampleObject :NSObject

@end

@implementation SampleObject

- (void)dealloc{

NSLog(@"dealloc %@",[self class]); 

}

@end

第二步:实例化该类,并在block中调用它;(没有加strong修饰符,三秒后释放该对象)

SampleObject* sample = [[SampleObject alloc]init];

self->sample= sample;

__weakSampleObject* weaksample = self->sample;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

NSIntegercount =0;

//__strong SampleObject* strongsample = weaksample;

while(count<10) {

count++;

NSLog(@"aaa %@",weaksample);

sleep(1);

}

});

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

self->sample=nil;

});

打印结果如下(没有用strong修饰符的打印结果如下):


839134-00ac2a45d0d21b16.png

结论是:如果仅仅使用__weak去修饰变量,当别处把变量释放后,block中该变量也会被释放掉

那么好,我们在把第二步中的方法修改一下,加上strong修饰符:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

__strongSampleObject* strongsample = weaksample;

NSIntegercount =0;

while(count<10) {

count++;

NSLog(@"aaa %@",strongsample);

sleep(1);

}

});

打印结果如下:


839134-d06a9b6fec3bd46e.png

结论是当加上修饰符strong时,当别处把变量释放掉,但调用该变量的block如果仍然没有执行结束,那么系统就会等待block执行完成后再释放,对该变量在block中的使用起到了保护作用。当block执行结束后会自动释放掉。

(上面解释如有问题,欢迎指正)

相关文章

网友评论

  • LV大树:strongself 不要乱用,特别是很占内存的controller .那一次,我的地图controller上用了这个strongself ,结果内存久久不释放。
  • 鸟人扎墨客:前几天面试还真有人问到 __weak __strong 使用场景
    叶小合:请问你是怎么回答的
    鸟人扎墨客:@_理_想_ 嗯
    8d95719e3241:面试成功了吗?
  • HiIgor:在block里面添加为什么不会造成循环引用呢?
    3b1ae4c6ef21:@断肠人在摸虾 block里边的strong修饰的strongsample,是自动变量
  • 苦笑男神:学习了,,不过我感觉,大部分情况下,不需要在Block里加strong了。。。分析结论是strong是为了防止野指针,而Block里大部分是用weakSelf访问self的属性,而不是局部变量。
    bc20007d7352:确实对于self没啥必要
    258b1f72bd91:@日月神话的爱 我觉着对于self也是没有必要的,我们不可能主动释放self的,最近正在困扰我,究竟需要不需要呢?
  • reloadRen:很赞!get

本文标题:block 中使用__weak 和__strong修饰符的问题

本文链接:https://www.haomeiwen.com/subject/akekhttx.html