由《网易面试OC多线程题目》引发后续的思考

秉持着科学严谨的态度,保持着对知识获取的怀疑,对于上一篇博客说,错误的原因,网友们讨论众说纷纭,我们根据主流的几个说法进行逐一验证,找出最科学,最符合逻辑的答案。

1、把 DISPATCH_QUEUE_CONCURRENT这个改成DISPATCH_QUEUE_SERIAL
运行成功未崩溃

 缺点:i<1000000,内存开销就跑到了**100.4mb**,单一个for循环语句就跑这么多内存,肯定是不符合要求的

serial

根据上面的测试结果,serial可以让程序正常运行不崩溃,但是内存开销太大,这种方案并不可取。

2、 加上synchronized的加锁代码块,保证每一次语句调用独占该锁

        `@synchronized (self) {
            self.target = [NSString stringWithFormat:@"ksddkjalkjd%d",i];
            NSLog(@"%@",self.target);
        }`

运行成功未崩溃
这里写图片描述

缺点:同上,内存占用资源过大,不可取。

3、 target应该没有被release掉,因为是强引用。问题是出在

[NSString stringWithFormat:@"ksddkjalkjd%d",i] 
dispatch_async(queue, ^{
                self.target = [NSString stringWithFormat:@"ksddkjalkjd%d",i];
                NSLog(@"%p--->,%@",self.target,self.target);

        });
在这里打印了指针地址,崩在了i==999939的地方,我们打印一个距离此处较远处的地址
2017-09-14 14:11:12.883 blogTest[9609:766744] 0x608007e44950--->,ksddkjalkjd675959

这里写图片描述

此时仍然能够打印出675959处的字符串,说明该地址字符串还未被销毁,甚至再找到i值更小的地址打印,结果一样能打印出相应值,那么是在999939处才开始release之前的字符串?所以导致的崩溃?

我们去掉字符串中读取i的地方再运行一次

dispatch_async(queue, ^{
    self.target = [NSString stringWithFormat:@"ksddkjalkjd"];
    NSLog(@"%@",self.target);
});

运行成功未崩溃

实验表明这个 i 和运行的崩溃息息相关,那么我们思考一下:

在崩溃出po一下这个 i,果然出错了
i出错

说明真正正确的答案是,for循环已经走完了,代码块内的局部变量i已经注销了,而异步运行的字符串format那里仍然在调用i,所以崩溃。这样也解释了上面串行、加锁等行为也能阻止崩溃的产生。

所以,别人的博客不一定都是对的,即使是在cocoachina首页上的文章,多试验多思考,找到正确的答案,才有助于自己的提高。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值