__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.

时间: 2024-10-25 02:44:46

__block在MRC ARC下的区别的相关文章

@autoreleasepool在ARC和MRC下的区别

MRC这个词应该是我编的,ARC,Automatic Reference Counting,手工引用计数就应该是:Manual Reference Counting,那就应该是MRC喽,不过没有见人这样用过. ARC引入了新的语句管理自动释放池语法: @autoreleasepool {     // Code, such as a loop that creates a large number of temporary objects.} 测试了一下,在ARC情况下和MRC情况下对象的释放有

__block在ARC和非ARC下有什么不同

一般在block中修改变量都需要事先加block进行修饰.在非arc中,block修饰的变量的引用计算是不变的.在arc中,会引用到,并且计算+1:非arc下可使用(arc直接使用__weak即可) //非ARC __block typeof(self) weakSelf = self; self.myBlock = ^(int paramInt){ //使用weakSelf访问self成员 [weakSelf anotherFunc]; }; 这样可以解决循环引用问题. starain Dou

__block在arc和非arc下含义一样吗?

Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC下返回Block). 比如这样一个Block类型: typedef void (^MyBlockType)(int); @property (copy) MyBlockType myBlock; if (self.myBlock) { //此时,走到这里,self.myBlock可能被另一个线程改为空,造成crash //注意:a

iOS——在ARC下引入MRC文件

在写一些工程时我们总是要引入一些第三方文件,但是这些文件有些是MRC下的有些是ARC下的.所以我们要进行转换. 引入三方文件时首先要阅读引入的文件的.h 文件头部信息 如下面的文件:头部文件要求:Header Search Paths包含/usr/include/libxml2 Other Linker Flags包含-lxml2 所以 在Bulid Setting下进行搜索 搜索后对其进行修改 对.h文件所要求的路径进行一一添加,添加完成后,就是把让MRC得文件在ARC的工程下进行运行 首先在

八.OC基础加强--1.autorelease的用法 2.ARC下内存管理 3.分类(category)4.block的学习

1.autorelease的用法   1.自动释放池及autorelease介绍 (1)在iOS程序运行过程中,会创建无数个池子,这些池子都是以栈结构(先进后出)存在的. (2)当一个对象调用autorelease时,会将这个对象放到位于栈顶的释放池中 . 2.为什么会有autorelease? OC的内存管理机制中比较重要的一条规律是:谁申请,谁释放. 但有些情况下,开发者并不能确定某些对象何时释放.这时候就需要自动释放池. 它的好处是: (1)不需要再关心对象释放的时间 : (2)不需要再关

__weak与__block修饰符到底有什么区别

API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables in the same lexical scope. You signal that a block can modify a variable using the __block storage type modifier. //At function level are __block vari

ARC下需要注意的内存问题

之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也有好多人反馈看不太懂,这次谈谈iOS中ARC的一些使用注意事项,相信做iOS开发的不会对ARC陌生啦.这里不是谈ARC的使用,只是介绍下ARC下仍然可能发生的内存泄露问题,可能不全,欢迎大家补充. Ps:关于ARC的使用以及内存管理问题,强烈建议看看官方文档,里面对内存管理的原理有很详细的介绍,相信用过MRC的一定看过这个. 另也有简单实用的ARC使用教程:ARC Best Practices 在2011年的WWDC中,苹果提到90

ARC下需要注意的内存管理

ARC下需要注意的内存管理 2016/04/03 · iOS开发 · 内存管理 分享到:1 原文出处: 一不(@luoyibu) 之前发了一篇关于图片加载优化的文章,还是引起很多人关注的,不过也有好多人反馈看不太懂,这次谈谈iOS中ARC的一些使用注意事项,相信做iOS开发的不会对ARC陌生啦.这里不是谈ARC的使用,只是介绍下ARC下仍然可能发生的内存泄露问题,可能不全,欢迎大家补充. Ps:关于ARC的使用以及内存管理问题,强烈建议看看官方文档,里面对内存管理的原理有很详细的介绍,相信用过M

ARC下block使用情况

ARC与MRC的block有着一些区别,笔记整理ARC的block,仅仅是自己参考的笔记,详情请参考 http://www.cnbluebox.com/?p=255 在开始之前,请新建一个Model类,写几个如下的属性,用于后面测试block的特性. Block的类型与内存管理 根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock. NSGlobalBlock:类似函数,位于text段: NSStackBlock:位于栈内存,