跟大家讲一讲MRC和ARC下属性Block的循环引用问题

 

  最近有个朋友看了我的博客,吐槽说,能不能发一些基础性的教学之类的,说实话,基础性的一些东西我虽然记得,但是你叫我总结的话我真的总结不出来,现在唯一能做的就是如果平时想到哪些以前遇到的一些Bug比较让我觉得有意思的话,我就把他给写出来了,

  刚开始学iOS的人必定会被他的循环引用所烦死,最烦的莫过于属性Block的循环引用问题,我这写了一下关于MRC和ARC下的循环引用问题;

  

typedef void(^Block)();

 

@interface ViewController ()

 

@property (nonatomic, copy)Block block;

 

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

////    1.未加__block的时候

//    NSLog(@"最初的self.retainCount_%ld",self.retainCount);

//    //打印: 最初的self.retainCount_3

//     UIViewController *weakSelf = [self retain];

//    NSLog(@"&weakSelf__%p__self.retainCount__%ld",&weakSelf,self.retainCount);

//    

//    //&weakSelf__0x7fff56402ab8__self.retainCount__4

//    

//    //block一旦实现则存储在堆区,则也相当于一个对象

//    self.block = ^(){

//        weakSelf.view.backgroundColor = [UIColor redColor];

//        //block里头的weakSelf成为了野指针,且引用计数增加

//        NSLog(@"Block里头&weakSelf__%p__self.retainCount__%ld",&weakSelf,       weakSelf.retainCount);

//        //打印:Block里头&weakSelf__0x7fa393d43080__self.retainCount__5

//    };

//    self.block();

//    

//    NSLog(@"&weakSelf____%p__self.retainCount__%ld",&weakSelf,self.retainCount);

//    

//    //&weakSelf____0x7fff56402ab8__self.retainCount__5

//

//    //即使release之后,self.retainCount也只是回到4,并没有回到3

//    [weakSelf release];

//    

    

//    加了__block之后;

    

    NSLog(@"最初的self.retainCount_%ld",self.retainCount);

    

    //打印: 最初的self.retainCount_3

  __block  UIViewController *weakSelf = [self retain];

    NSLog(@"&weakSelf__%p__self.retainCount__%ld",&weakSelf,self.retainCount);

    

    //打印&weakSelf__0x7fff57762ab8__self.retainCount__4

 

    

    //block一旦实现则存储在堆区,则也相当于一个对象

    self.block = ^(){

        weakSelf.view.backgroundColor = [UIColor redColor];

        //因为加了__block即使拷贝了新的一份,也导致引用计数也不会增加

        NSLog(@"Block里头&weakSelf__%p__self.retainCount__%ld",&weakSelf,weakSelf.retainCount);

        //打印 &weakSelf__0x7f8392c1aeb8__self.retainCount__4

    };

    self.block();

    

    NSLog(@"&weakSelf____%p__self.retainCount__%ld",&weakSelf,self.retainCount);

    //此时&weakSelf是真的改变了

    //&weakSelf____0x7f8392c1aeb8__self.retainCount__4

    [weakSelf release];

    //引用计数回到初始值3;

    }

  

  MRC的属性block的循环引用问题综算解决了,但是问题又来了既然加了__block可以解决问题,那么为什么不能够在ARC状态下写__block呢?

  原因很简单,因为在ARC下,由于__block抓取的变量一样会被Block retain,所以必须用弱引用才可以解决循环引用问题,iOS 5之后可以直接使用__weak,之前则只能使用__unsafe_unretained了;

  好了,大概就讲完了,大家好好消化吧;

 

 

 

    

    

    

 

posted @ 2016-03-19 13:10  6Xa天  阅读(658)  评论(0编辑  收藏  举报