dispatch_async(dispatch_get_main_queue(), ^{

[weakSelf updateView4SwiperSuccess:result];

});
上面这段代码,在 ARC有问题但是不会引起,因为weakSelf 释放后会被置为nil,OC语法向一个空的对象发送消息是不会崩溃的,虽然不会崩溃,但是原有逻辑却走不了了。
在MRC下会出现野指针的情况,即执行到block的时候,weakself 引用的self 已经释放,而self 属性是unsafe_unretained。所以这段block是不安全的。
那么上面这段代码如何正确的使用呢?

dispatch_async(dispatch_get_main_queue(), ^{

[self updateView4SwiperSuccess:result];

});
对你没看错,就是这样使用,里面不需要使用weakSelf。
block 引用self, self 引用计数+1,当block 执行完毕释放时候self 引用计数减1,伪代码如下

dispatch_async(dispatch_get_main_queue(), ^{

    //_Block_object_assingn(&self); self  retain
    [self updateView4SwiperSuccess:result];
    //_Block_object_dispose(&self); self release

});

我们要清楚的知道什么时候使用weakself,weakself是在有循环引用的情况下使用的。即 a引用b,b也引用a。而GCD block里面只引用了self ,self并没有引用gcd 的block所以不需要用weakself。 下面示例的代码也一样。

NSObject *testObject = [[NSObject alloc] init];

testObject.testBlock = ^(){
    [self doSomeThing];
};
[testObject release];

上面这段代码也不需要用weakself,很简单 [testObject release];执行后 testObject 进度dealloc函数 释放它的成员变量,包括testblock,testblock释放调用函数_Block_object_dispose()释放外部变量。所以不会循环引用,但是如果上面代码写成这样就会出现循环引用了

-(void)test

 self.testObject = [[NSObject alloc] init];
   self.testObject.testBlock = ^(){
            [self doSomeThing];
        };

}

  • (void)dealloc
    {

    self.testObject  = nil;

    }

上面这段函数就出现了循环引用,self,等待testobject释放,而testobject也在等待self释放,这样就造成了循环引用。对于上面这段代码循环引用的原理我就不详细解释了。(转)


Eidesen
427 声望16 粉丝

专注iOS,Swift开发,总结了一下自己项目中遇到的问题,及解决方案。欢迎小伙伴讨论和多多指教--->记得顺手点个关注额(⊙o⊙)…。


引用和评论

0 条评论