Xcode ARC详解全攻略

news/2024/7/20 16:08:50 标签: xcode, 移动开发, 内存管理

Xcode ARC详解全攻略

2013-04-15 10:48 蓄积待发 blog.163  我要评论(0) 字号: T |  T
一键收藏,随时查看,分享好友!

ios5中,有个很吸引眼球的特性就是“Automatic Reference Counting”,简单来说就是内存自动回收,看起来似乎是平时开发中遇到的各种内存问题的福音,仔细了解了一下,似乎没有那么美好:1、需要iOS5才支持;2、很多引用的类库暂时还不支持.麻烦的是对大多数第三方库需要加禁用arc的编译flag,因为大多都因为兼容性还在使用手动内存管理

AD:2013云计算架构师峰会精彩课程曝光

 

iOS上内存管理一直让人很头疼.

手动管理内存经常忘掉release或autorelease,或者因为release多了、retain少了导致空指针引用程序崩溃,还要经常按COMMAND+SHIFT+B,岂止头疼,简直蛋疼有木有。

虽然objective-c 2.0支持垃圾收集器(Garbage Collection,简称GC),但是垃圾收集器只能在MAC程序上开启,ios上没办法用。就算在MAC应用程序上可以用,GC也会有性能上的损耗。

现在LLVM3.0多了一个给力的新东西,叫Automatic Reference Counting。开启这个选项之后,LLVM会在编译阶段自动帮开发者完成“手动”的内存管理。同时,所有代码中的retain,release和 autorelease会被标记成错误,也就是说,我们完全不需要用以前头蛋俱疼的方式管理内存了。

ARC不仅可以修复错误,还能增强性能。根据WWDC 2011大会的介绍,retain/release快了2.5倍,@autoreleasepool快了6倍,objc_msgSend快了33%。

一、旧工程开启ARC的方法

xCode4.2中已经自带了LLVM3.0,在用新的模板建立工程时,编译器默认选择LLVM3.0,并且开启ARC。如图。

xCode4.2 也为ARC提供了自动转换工具。首先将工程的编译器切换为LLVM3.0,然后在菜单里选择Edit—-Refactor—-Convert to Objective-C ARC…。LLVM会将不能转换的部分标记为错误,要求我们手动修改。一般NSAutoReleasePool不能自动转换,要手动转为 @autoreleasepool。CF框架的方法也不能自动转换,而release、retain和autorelease是可以自动转换的。我们将不 能自动转换的错误手动修改好后,编辑器将完成自动转换。

对 于可能出现的错误,WWDC 2011的视频中给出了一些例子。比如用static count来处理singletons pattern;用weak来申明delegate pattern;用dispatch_once来保证多线程的安全;在case关键字后面加上大括号{..}来限制case里面申明变量的作用范围等等。

二、开启ARC后需要遵循的原则

1、不能调用retain/release/autorelease,这些由编译器来完成。

2、结构内不能有对象指针,如果结构中包含,则需要以类代替结构。

3、不能使用id<–>void *的类型转换,因为编译器不知道这个void *是否需要retained。

4、不能使用NSAutoreleasedPool,要用@autoreleasepool {……}来代替。

三、ARC中引入的四个新的关键字

1、Strong Reference,强引用。默认类型,不加任何关键字(也可以写成__strong)。相当于之前代码中的retain属性。

2、Autoreleasing Reference,自动释放引用。通常出现在例如系统error处理函数中(关键字__autoreleasing),描述out-parameters用,只保存在栈中,不太常用。

3、Unsafe Reference,不安全引用。类似于之前代码中的assign属性,不分配内存(关键字__unsafe_unretained),相当于起了个别名。

4、Weak Reference,弱引用。前面提到过,不增加计数,当对象开始释放时,立刻设置成nil。

四、ARC中循环引用造成内存泄露的原因与解决办法

ARC通过记录指向某对象的指针数量来判断该对象是否应该被释放(0代表可以释放)。因而如果出现循环引用,就会出现内存泄露。如下图所示。

 取消3->2的引用   导致泄露。

ARC的解决办法也和简单,使用弱引用(weak reference)。弱引用的申明方式举例如下:
id __weak P;
@property (weak) NSVIew *V;
还是以上面的例子做对比,结果如下:

 弱引用不增加计数, 从而消除leak。

五、Instruments的Leaks的新功能

这张图里面就标识出了整个leak cycle的全景图。点击cycle graph中的红色箭头,就会自动跳到code中对应的变量声明处,根据情况加上weak关键字就解决leak了。
在新旧技术更替的更年期应注意:现在ARC还under NDA,没有任何开源框架可以公开支持ARC的,如果想使用此特性,在选取开源框架时应该尽量选择使用CF库较少的框架,否则手动爆开源框架的菊花会很痛苦。

http://www.niftyadmin.cn/n/591758.html

相关文章

Xcode 中设置部分文件ARC支持

ARC是什么 ARC是iOS 5推出的新功能&#xff0c;全称叫 ARC(Automatic Reference Counting)。简单地说&#xff0c;就是代码中自动加入了retain/release&#xff0c;原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。该机制在 iOS 5/ Mac OS X 10.…

虚拟机中ubuntu用锐捷连接网络,ubuntu安装vm tools

第一步&#xff1a;安装Vmware Tools 首先&#xff0c;点击VM --> Install VMware Tools 然后&#xff0c;在Ubuntu下会自动加载linux版的VMware Tools的安装包。如我的就是VMwareTools-9.2.0-799703.tar.gz 接着&#xff0c;把安装文件cp到/home目录下 然后执行下面的命…

UISegmentedControl

UISegmentedControl的详细使用 当用户输入不仅仅是布尔值时&#xff0c;可使用分段控件&#xff08;UISegmentedControl&#xff09;。分段控件提供一栏按钮&#xff08;有时称为按钮栏&#xff09;&#xff0c;但只能激活其中一个按钮。分段控件会导致用户在屏幕上看到的内容发…

Mac系统下Android SDK更新以及ADT无法在线下载

无法更新和下载androidSDK打开SDK Manager时底部进度条一直不动&#xff0c;打开详细信息&#xff0c;发现卡在&#xff1a; 1Fetching https://dl-ssl.google.com/android/repository/addons_list-2.xml 解决办法&#xff1a; 修改hosts文件。&#xff08;1&#xff09;window…

Qt实例 1_3 各类位置信息

QT源代码&#xff08;在qt5.10版本上测试通过&#xff09; geometry.h #ifndef GEOMETRY_H #define GEOMETRY_H #include <QDialog> #include <QLabel> class Geometry : public QDialog { Q_OBJECT public: Geometry(); QLabel *label1; QLabel *label2; QL…

ARC中__bridge, __bridge__transfer, __bridge_retained 关系

转在开头&#xff1a;转在这篇文章是因为我遇到一个问题&#xff0c;这篇文章解决了我这个问题&#xff0c;debug&#xff1a;cast of objective- c pointer type NSMutableDictionary * to C pointer ----——同时向此文的原作者致敬&#xff01; 总结于 IOS Tuturial 中 ARC两…

Phonegap for IOS Plugin插件开发

1.新建Phonegap工程MyPlugin 环境 xcode4.5.1 phonegap2.1.0 2.在Plugin文件夹下创建实现Plugin子类 [plain] view plaincopyprint? // // MyPlugin.h // MyPGPlugin // // Created by kllmctrl on 12-10-29. // // #import <Cordova/CDV.h> interface M…

UIButton---iOS

1.button更改按下的背景图片 [btn setImage:bgImg1 forState:UIControlStateHighlighted]; 设置Button的字体大小&#xff1b; btn.titleLabel.font [UIFont systemFontOfSize: 14.0]; UIButton去掉系统的按下高亮置灰效果 [downImageV setAdjustsImageWhenHighlighted:NO]; U…