__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....\r\n\r\n\r\n\r\n");

}

日志

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....\r\n\r\n\r\n\r\n");

}

日志

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.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM