研究下__block在MRC/ARC下區別,直接上代碼。atom
@property (nonatomic,copy) TestBlock block;//定義的blockspa
一._NSConcreteStackBlock日誌
- (void)stackBlock{對象
NSLog(@"stackBlock start....");it
Person *person = [[Person alloc]init];person.personName = @"張三";class
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){d3
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.