• __block在MRC ARC下的区别


    研究下__block在MRC/ARC下区别,直接上代码。

    @property (nonatomic,copy) TestBlock   block;//定义的block

    一._NSConcreteStackBlock

    - (void)stackBlock{

        NSLog(@"stackBlock start....");

        Person *person = [[Person alloc]init];person.personName = @"张三";

        NSLog(@"person RetainCount is %ld", CFGetRetainCount((__bridge CFTypeRef)person));

        __block  Person *blockPerson = person;

        NSLog(@"blockPerson RetainCount is %ld", CFGetRetainCount((__bridge CFTypeRef)blockPerson));

        void (^block)(int a) = ^(int a){

            NSLog(@"block blockPerson 111   is %ld", CFGetRetainCount((__bridge CFTypeRef)blockPerson));

            NSLog(@"block person 111  is %ld", CFGetRetainCount((__bridge CFTypeRef)person));

      NSLog(@"block self  is %ld", CFGetRetainCount((__bridge CFTypeRef)self));

        };

        NSLog(@"block is %@",block);

        block(2);

        NSLog(@"block blockPerson 2222 is %ld", CFGetRetainCount((__bridge CFTypeRef)blockPerson));

        NSLog(@"block person 222 is %ld", CFGetRetainCount((__bridge CFTypeRef)person));

    #if !__has_feature(objc_arc)

        [person release];

    #endif

        NSLog(@"stackBlock end.... ");

    }

    日志

    MRC

    2016-03-17 16:32:25.253 ARCAndMRC[12313:228133] stackBlock start....

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] person RetainCount is 1

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] blockPerson RetainCount is 1

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] block is <__NSStackBlock__: 0xbff9c100>

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] block blockPerson 111   is 1

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] block person 111  is 1

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] block blockPerson 2222 is 1

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] block person 222 is 1

    2016-03-17 16:32:25.254 ARCAndMRC[12313:228133] Person release ..:张三

    2016-03-17 16:32:25.255 ARCAndMRC[12313:228133] stackBlock end....

    ARC下

    2016-03-17 17:14:22.662 ARCAndMRC[13677:260528] stackBlock start....

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] person RetainCount is 1

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] blockPerson RetainCount is 2

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] block is <__NSMallocBlock__: 0x7c92cf40>

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] block blockPerson 111   is 4

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] block person 111  is 4

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] block self  is 3

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] block blockPerson 2222 is 4

    2016-03-17 17:14:22.663 ARCAndMRC[13677:260528] block person 222 is 4

    2016-03-17 17:14:22.664 ARCAndMRC[13677:260528] stackBlock end....

    2016-03-17 17:14:22.664 ARCAndMRC[13677:260528] Person release ..:张三

    根据日志可以看出,MRC下__block修饰的变量,并不改变引用计数,同时block内部并不对引入的外部对象,更改引用计数。

    ARC下block会被修改为__NSMallocBlock__ ,同时引用计数增加了。

     

    2._NSConcreteMallocBlock

    - (void)mallocStack{

        NSLog(@"mallocStack start....");

        Person *person = [[Person alloc]init];person.personName = @"张三";

        NSLog(@"person RetainCount is %ld", CFGetRetainCount((__bridge CFTypeRef)person));

        __block  Person *blockPerson = person;

         NSLog(@"blockPerson RetainCount is %ld", CFGetRetainCount((__bridge CFTypeRef)blockPerson));

        self.block = ^(int a){

            NSLog(@"block blockPerson 111   is %ld", CFGetRetainCount((__bridge CFTypeRef)blockPerson));

            NSLog(@"block person 111  is %ld", CFGetRetainCount((__bridge CFTypeRef)person));

      NSLog(@"block self  is %ld", CFGetRetainCount((__bridge CFTypeRef)self));

        };

        NSLog(@"self.block is %@", self.block);

        self.block(2);

        NSLog(@"block blockPerson 2222 is %ld", CFGetRetainCount((__bridge CFTypeRef)blockPerson));

        NSLog(@"block person 222 is %ld", CFGetRetainCount((__bridge CFTypeRef)person));

     #if !__has_feature(objc_arc)

        [person release];

    #endif

        NSLog(@"mallocStack end.... ");

    }

    日志

    MRC

    2016-03-17 17:27:33.739 ARCAndMRC[14065:269749] mallocStack start....

    2016-03-17 17:27:33.739 ARCAndMRC[14065:269749] person RetainCount is 1

    2016-03-17 17:27:33.739 ARCAndMRC[14065:269749] blockPerson RetainCount is 1

    2016-03-17 17:27:33.739 ARCAndMRC[14065:269749] self.block retaincount is 1 <__NSMallocBlock__: 0x7ae09d30>

    2016-03-17 17:27:33.739 ARCAndMRC[14065:269749] block blockPerson 111   is 2

    2016-03-17 17:27:33.739 ARCAndMRC[14065:269749] block person 111  is 2

    2016-03-17 17:27:33.740 ARCAndMRC[14065:269749] block self  is 2

    2016-03-17 17:27:33.740 ARCAndMRC[14065:269749] block blockPerson 2222 is 2

    2016-03-17 17:27:33.740 ARCAndMRC[14065:269749] block person 222 is 2

    2016-03-17 17:27:33.740 ARCAndMRC[14065:269749] Person release ..:张三

    2016-03-17 17:27:33.740 ARCAndMRC[14065:269749] mallocStack end....

    ARC

    2016-03-17 17:28:45.643 ARCAndMRC[14118:271047] mallocStack start....

    2016-03-17 17:28:45.643 ARCAndMRC[14118:271047] person RetainCount is 1

    2016-03-17 17:28:45.643 ARCAndMRC[14118:271047] blockPerson RetainCount is 2

    2016-03-17 17:28:45.643 ARCAndMRC[14118:271047] self.block retaincount is 1 <__NSMallocBlock__: 0x7b23ed00>

    2016-03-17 17:28:45.643 ARCAndMRC[14118:271047] block blockPerson 111   is 4

    2016-03-17 17:28:45.644 ARCAndMRC[14118:271047] block person 111  is 4

    2016-03-17 17:28:45.644 ARCAndMRC[14118:271047] block self  is 3

    2016-03-17 17:28:45.644 ARCAndMRC[14118:271047] block blockPerson 2222 is 4

    2016-03-17 17:28:45.644 ARCAndMRC[14118:271047] block person 222 is 4

    2016-03-17 17:28:45.644 ARCAndMRC[14118:271047] mallocStack end....

    根据日志可以看出,MRC下__block修饰的变量,并不改变引用计数,但是block内部对引入的外部对象,会更改引用计数。所以要及时对block进行release.

    ARC下,block修饰的引用计数会增加,同时block内部持有的对象引用计数会增加,所以

    person没有被释放,原因是block内部持有了self,导致self没有被释放,这就会导致循环引用,所以需要使用weak.

     

  • 相关阅读:
    Django ---uploads files
    powershell 更改为Oh-my-zsh
    Ubuntu server 安装Mysql
    Ubuntu下安装Python多版本开发环境
    python virtualenv 虚拟开发环境
    csv文件操作
    Could not load file or assembly ADODB, Version=7.0.3300.0
    sqlserver 循环截取字段中的某些字符
    JSON序列化的长度
    为何HttpContext.Current为NULL
  • 原文地址:https://www.cnblogs.com/menchao/p/5288429.html
Copyright © 2020-2023  润新知