MRC转ARC
转载请注明出处:http://blog.csdn.net/cywn_d/article/details/18222671
1.删除所有retain,release和autorelease。
2.把原来property写retain和assign的地方替换成strong或者weak.
3.MRC需要自己retain一个想要保持的对象,而现在不需要了。现在唯一要做的是用一个指针指向这个对象,只要指针没有被置空,对象就会一直保持在堆上。当将指针指向新值时,原来的对象会被release一次。
4.必须在合适的地方把strong指针手动设置到nil。
以下两行代码,如果是MRC,那么array[0]对象在remove后将销毁,而在ARC下,由于对象是strong的,所以obj持有array[0]的那个对象,即使array将array[0]对象移除,该对象依然被obj持有。
id obj = [array objectAtIndex:0];
[array removeObjectAtIndex:0];
5.dealloc并没有做除了release和super dealloc之外的任何事情,直接删除整个delloc方法就可以了。
6.有些地方要进行桥接转换的,要根据情况加上bridge,bridge_transfer和__bridge_retained三个关键字中的一个。
7.不使用ARC的文件,在Build Phases-Compile Sources的文件中双击,输入-fno-objc-arc。
8.ARC forbids Objective-C objects in structs or unions
ARC机制下,struct里面不能定义OC对象。在出错的地方添加__unsafe_unretained,但是可能会产生问题。
9.关于MRC与ARC混编译时引用框架可能产生的问题
MRC和ARC混编译主要的解决方法是使用 -fno-objc-arc编译标记。
普通的项目可以通过设置-fno-objc-arc编译标记,成功使用MRC和ARC混编译。
但是有一种情况不可以:
就是在项目里引用了一个framework的.h头文件,这个头文件有写地方不符合ARC规范,可能有两种解决方法,
第一种是把这个头文件不符合ARC的地方改成符合ARC,但是,这可能会影响到这个框架里面.m文件的使用。我们无法看到里面的细节,所以也无法确认会不会存在问题。
第二种是把这个头文件的.m文件设置为非ARC,即加上 -fno-objc-arc编译标记。可是框架里面的.m文件是不可见的,我们无法对其进行设置。可能只需要把引用了这个头文件的.m文件设为非ARC就可以,还未测试。
10.关于桥接转换:
自由桥接对象:在Cocoa框架中,有很多顶层对象对底层的抽象,而在使用中我们往往可以不加区别地对这两种对象进行同样的对待,这类对象即为可以”自由桥接”的对象(toll-free bridged)。NSURL和CFURLRef就是一对好基友好例子,在这里其实CFURLRef和NSURL是可以进行替换的。
Core Foundation最聪明的地方体现在它能和Foundation无障碍地交换数据。比如说,任何接受NSArray
的函数或方法同样也接受CFArray
,只要经过一次桥接转换即可。**桥接转换**(bridge
cast)是给编译器的指令,告诉它如何处理自动引用计数。
在很多情况下,只需要使用__bridge
修饰符,如下代码所示:
1 |
NSArray *nsArray = [NSArray arrayWithObject:@"Foo"]; |
这其实是告诉编译器什么都别做。它只要简单地把nsArray
转换为CFArrayRef
,并传给CFArrayGetCount
。nsArray
的引用计数没有变化。
反过来也一样:
1 |
CFMutableArrayRef cfArray = |
只要没有Core Foundation的内存管理介入,__bridge
转换就管用。在上面的例子中,我们没有把结果赋给变量或者返回结果。然而,考虑下面这种情况:
1 |
- (NSString *)firstName { |
怎样才能正确转换cfString
?在ARC之前,要把它转换成NSString
,然后调用autorelease
。有了ARC,就无法调用autorelease
了,而ARC不知道cfString
还有一个来自CFStringCreate...
的保留。还是得用桥接转换,只不过这次是以下例所示的函数:
1 |
return CFBridgingRelease(cfString); |
这个函数把所有权从Core Foundation转移到ARC。在这个过程中,它把引用计数减1以平衡CFStringCreate...
。必须用桥接转换才能做到这一点,调用CFRelease
会在返回对象前就销毁对象。
在把一个对象从ARC转移到Core Foundation时要用CFBridgeRetain
,它会把引用计数加1,如下代码所示:
1 |
CFStringRef cfStr = CFBridgingRetain([nsString copy]); |
桥接函数也可以写成类型转换的形式,如下:
1 |
NSString *nsString = CFBridgingRelease(cfString); |
CFTypeRef
是指向Core Foundation的通用指针,而id
是指向Objective-C对象的通用指针。这里也可以用具体的类型,像CFStringRef
和NSString*
。
函数形式更简短,也更容易理解。CFBridgingRelease
和CFBridgingRetain
应该只用在对象在ARC和Core Foundation之间转移时。它们不是CFRetain
和CFRelease
的替代品,也不是“欺骗”编译器给Objective-C对象施加额外的retain
或release
操作的方法。一旦对象从Core Foundation转移到ARC,就不应该再使用Core Foundation变量了,应该将其置为NULL
。相反,当从ARC转换到Core Foundation,要马上把ARC变量设置为nil
。这里已经把所有权从一个变量转到了另一个变量,因此旧变量应该无效。
自由桥接不仅可以方便地在C和Objective-C之间转移信息,还能让Cocoa开发者用上某些只有Core Foundation有(而Objective-C没有等价功能)的函数。比如,CFURLCreateStringByAddingPercentEscapes
提供的转换功能比它所对应的NSURL
的stringByAddingPercentEscapesUsingEncoding:
方法强大得多。
一些不显式支持自由桥接的类型也能桥接为NSObject
。这意味着能在Cocoa容器对象中存储Core Foundation对象(即使没有等价的Cocoa类),如下例所示:
1 |
CFTreeContext ctx = {0, (void*)CFSTR("Info"), CFRetain, |
自由桥接是用相当直观的方式实现的。每个Objective-C对象结构体都是以一个指向Class
的ISA指针开始的:
1 |
typedef struct objc_class *Class; |
Core Foundation不透明类型则以一个CFRuntimeBase
开始,而它的第一个元素也是ISA指针:
1 |
typedef struct __CFRuntimeBase { |
_cfisa
指向自由桥接的Cocoa类,这是等价的Cocoa类的子类,它们会把Objective-C方法调用转发为等价的Core Foundation函数调用。比如,CFString
桥接到私有的自由桥接类NSCFString
。
如果没有显式桥接类,那么_cfisa
指向__NSCFType
,这是NSObject
的子类,可以转发retain
和release
等类似调用。
为了支持把Objective-C类传递给Core Foundation函数,所有公开的自由桥接函数看起来都类似如下所示:
1 |
CFIndex CFStringGetLength(CFStringRef str) { |
CF_OBJC_FUNCDISPATCH0
检查_cfisa
指针。如果对于给定的CFTypeID
,它匹配Core Foundation桥接类,那就把调用传给真正的Core Foundation函数
;否则,就把调用转化为Objective-C消息(在本例中是length
,以C字符串的形式给出)。
MRC转ARC的更多相关文章
- MRC迁移ARC之__block
今日帮着同事把老项目从MRC迁移至ARC,大部分工作无非是删除release,[super dealloc]等方法,只要关闭了MRC编译选项后,编译器能自动帮你检查,block就有一些不一样了,发现许 ...
- iOS-旧项目中手动内存管理(MRC)转ARC
在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题, ...
- Objective-c的内存管理MRC与ARC
Objective-c的内存管理MRC与ARC Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Referen ...
- 内存管理-MRC与ARC详解
Objective-C提供了两种内存管理机制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),为Objective-C提 ...
- MRC转ARC(2)
春节前抽空花了一天的时间将手头的工程从MRC转成了ARC,然后陆陆续续地修复一部分因为转ARC引起的内存泄漏和崩溃,到目前为止工程也算是比较稳定了,抽空记上一笔.(虽说这种事情这辈子估计都只会做这么一 ...
- @autoreleasepool在MRC和ARC中的区别
对于@autoreleasepool {} (1)在ARC中会销毁所有在里面创建的对象,即使你用外面的Strong指针指向他 (2)在MRC中如果有外部的强指针指向,不会销毁对象,retainCoun ...
- 【Bugly干货分享】iOS内存管理:从MRC到ARC实践
Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...
- MRC和ARC混编
iOS5.0以后就开始可以使用ARC( Automatic Reference Counting:自动引用计数)来代替之前的MRC(Manual Reference Counting:人工引用计数). ...
- MRC BlOCK ARC
/*-------------------MRC环境中-------------------------*/ //使用局部变量:a到block块中,为了在block中能够使用这个变量,将 ...
随机推荐
- Entity Framework Code First 迁移
Entity Framework CodeFirst数据迁移 http://www.cnblogs.com/aehyok/p/3325459.html Entity Framework Code Fi ...
- Ceph之对象存储网关RADOS Gateway(RGW)
一.Ceph整体架构及RGW在Ceph中的位置 1.Ceph的整体架构 Ceph是一个统一的.分布式的的存储系统,具有优秀的性能.可靠性和可扩展性.Ceph支持对象存储(RADOSGW).块存储(RB ...
- J20170524-hm
取りこぼし 意外地输给较自己实力弱的对手,爆出冷门,败给手下败将 振り分け 分配,整理 スキーマ 图解.模式.图式
- bzoj 4195: [Noi2015]程序自动分析【并查集】
等于有传递性,所以hash一下把等于用并查集连起来,然后再判断不等于是否合法即可 #include<iostream> #include<cstdio> #include< ...
- Python Flask 实现移动端应用接口(API)
引言 目前,Web 应用已形成一种趋势:业务逻辑被越来越多地移到客户端,逐渐完善为一种称为富互联网应用(RIA,rich Internet application)的架构.在 RIA 中,服务器的主要 ...
- Win7下安装MongoDB4.0.10
前言 MySQL与MongoDB都是开源的常用数据库,但是MySQL是传统的关系型数据库,MongoDB则是非关系型数据库,也叫文档型数据库,是一种NoSQL的数据库.它们各有各的优点,关键是看用在什 ...
- [SDOI2016]墙上的句子
题目描述 考古学家发现了一堵写有未知语言的白色墙壁,上面有一个n行m列的格子,其中有些格子内被填入了某个A至Z的大写字母,还有些格子是空白的. 一直横着或竖着的连续若干个字母会形成一个单词,且每一行的 ...
- 题解报告:hdu 1263 水果
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1263 Problem Description 夏天来了~~好开心啊,呵呵,好多好多水果~~ Joe经营 ...
- Oracle查看所有表空间的数据使用情况
-- 查看所有表空间的数据使用情况 SELECT Upper(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB "表空间大小(M)& ...
- Linux的proc文件系统 分类: linux 2014-06-02 10:21 623人阅读 评论(0) 收藏
proc为一个内核数据结构接口,用户空间和内核空间可以通过该接口通信, 与普通文件不同的是,这些虚拟文件的内容都是动态创建的. proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间. ...