The study under the __block under the MRC/ARC difference, directly on the code.
@property (nonatomic,copy) Testblock block;//defined block
I._nsconcretestackblock
-(void) stackblock{
NSLog(@ "stackblock start ...");
person *person = [[person alloc]init];p Erson. PersonName = @ " Zhang San ";
NSLog(@ "person Retaincount is%ld", cfgetretaincount(__bridge Cftyperef));
__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 ));
NSLog(@ "block self are%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 ));
#if!__has_feature (OBJC_ARC)
[Person release];
#endif
NSLog(@ "Stackblock end....\r\n\r\n\r\n\r\n");
}
Log
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 ...: Zhang San
2016-03-17 16:32:25.255 arcandmrc[12313:228133] stackblock end ....
Under 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 ...: Zhang San
According to the log it can be seen that the MRC under the __block modified variable, does not change the reference count, while the block interior is not the introduction of external objects, change the reference count.
The block under Arc is modified to __nsmallocblock__ , and the reference count is increased.
2._nsconcretemallocblock
-(void) mallocstack{
NSLog(@ "mallocstack start ...");
person *person = [[person alloc]init];p Erson. PersonName = @ " Zhang San ";
NSLog(@ "person Retaincount is%ld", cfgetretaincount(__bridge Cftyperef));
__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 ));
NSLog(@ "block self are%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 ));
#if!__has_feature (OBJC_ARC)
[Person release];
#endif
NSLog(@ "Mallocstack end....\r\n\r\n\r\n\r\n");
}
Log
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 ...: Zhang San
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 ....
As you can see from the log, the __block modified variables under MRC do not change the reference count, but the reference count is changed within the block to the imported external object. So we need to release the block in time.
Under Arc, the block modifier's reference count increases, and the object reference count held inside the block increases, so
The person is not released because self is held inside the block, causing self to not be freed, which causes circular references, so you need to use weak.
The difference between the __block under MRC Arc