春节前抽空花了一天的时间将手头的工程从MRC转成了ARC,然后陆陆续续地修复一部分因为转ARC引起的内存泄漏和崩溃,到目前为止工程也算是比较稳定了,抽空记上一笔。(虽说这种事情这辈子估计都只会做这么一次了,但是可以留点经验给后来的童鞋)

这个工程启动于12年底13年初,一开始人手少工期短,需要尽快地出demo,同时抱着对面世才一年多的ARC不太信任的态度沿用了最熟悉的MRC。但是随着工程投入的人手增多,使用MRC的各种缺点也暴露无遗:

1.零星的内存泄漏增多,导致每次发版本之前都要捋一遍:费时费力不讨好。虽然我一直觉得iOS下这种零星的内存泄漏并不是多大的事,真正压死一个App的泄漏永远是某些Bitmap的泄漏。但是这种零星泄漏仍旧会带来很多麻烦,所以还是需要解决一下。

2.无法享受到ARC下weak关键字带来的好处:总有童鞋忘记在对象析构时去置空delegate。一个比较典型的例子是带Scrollview(尤其是MKMapView)的VC。如果VC析构时不置空Scrollview的delegate,那么若此时Scrollview还正处于滑动状态,就很容易出现崩溃。原因是:Scrollview在滑动时有一个Timer retain自身,此时退出VC并不会使得Scrollview同步析构。而当Timer fire时,Scrollview调用其delegate方法就访问了野指针。

3.ARC下编译器对于retain cycle的检测更为严格。(个人使用后的感觉)

4.越来越多的第三方库只提供ARC版本,虽然打标记可以解决问题,但增加了无谓的工作。

基于以上4点理由,于是选了春节前一个月高风黑夜悄悄地完成工程的ARC转换。23333333333333333

准备工作

1.一个MRC模式的工程。(嗯!)

2.一个合适版本的XCode。(你是鸡丁?不,我是喜儿肉丝)虽然XCode4之后就支持了ARC的自动转换,但是对ObjC++的支持却还是在XCode5之后。

3.一台性能彪悍的机器。个人悲惨经历:某天下午用自己那台老爷机做了一次转换,结果在最后一步机器直接卡死,重启后XCode也无法使用,最后只得重装XCode了事。

使用XCode做最基本的转换

1.开启即使出错也继续编译的选项:"Preferences" -> "General" -> "continue building after error" 。当转换开始后工程将出现大量的错误,与其每次fix一个错误再来一遍,还不如一口气让编译器把所有的错误都先汇报出来,再一一解决。(我们的工程大约20来万代码,检查出了近200个错误)

2.检查第三方库和自己的代码。对于第三方库,有ARC版本就进行替换,没有则打上-fno-objc-arc的标记(当然如果第三方库比较简单,也可以直接做转换)。而自己的代码则推荐全部做ARC的转换。

3.使用XCode提供的Convert to Objective-C ARC功能,选择当前需要转换的工程并执行。

4.正常情况会出现比较多的错误和retain-cycle的warning,推荐优先解决掉所有error,而warning暂时不处理,等转换完毕编译通过后再进行处理。而error和warning一般也就是下面几种情况:

a.对于NSObject和CF对象没有使用bridge cast,大多数情况下直接按照XCode的推荐方式进行fix即可。

b.原来MRC下使用了ARC下不允许使用的方法,如NSMakeCollectable。

c.原先使用__block关键字避免循环引用的地方在ARC往往会引起循环引用,原因是__block在MRC和ARC下的语意不同,MRC下生成的__block结构体内只是简单地指向原值地址,而ARC下则是由__block结构体持有了原值,使用__weak进行修改即可。

处理完毕后重复第三步直到顺利编译通过。

后续处理

完成前面的步骤整个转换就算完成了百分之九十,但是正所谓行百里者半九十,接下去的任务更加艰巨,更需要认真对待。

1.检查工程内的所有文件,包括是否设置了合理的编译选项和被包含在工程内:XCode似乎有个bug,在转换完成后部分文件会被移出工程,部分文件原先打好的-fno-objc-arc标记也会被重置。

2.运行Instrument,检查内存泄漏:此时存在的内存泄漏大多是一些对ARC不适用的MRC写法。典型的情况便是将delegate作为类内部成员变量,在转换为ARC后系XCode并不会在这些变量前面打上weak的标记,导致了循环引用,需要自己手动添加。

3.对你的程序进行冒烟,尽量走完主流程,检查是否有必现崩溃。一般都是由错误的bridge cast和使用MRC时的不规范写法引起:如万恶的[self retain],在ARC转换时XCode直接去掉这句话,这样就导致原先依赖于此的类往往在初始化后就直接被释放,造成野指针访问。(吐槽下,无论是MRC还是ARC下,自己去拥有自己这种做法都是不太好的做法)

MRC转ARC(2)的更多相关文章

  1. MRC迁移ARC之__block

    今日帮着同事把老项目从MRC迁移至ARC,大部分工作无非是删除release,[super dealloc]等方法,只要关闭了MRC编译选项后,编译器能自动帮你检查,block就有一些不一样了,发现许 ...

  2. iOS-旧项目中手动内存管理(MRC)转ARC

    在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题, ...

  3. Objective-c的内存管理MRC与ARC

    Objective-c的内存管理MRC与ARC   Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Referen ...

  4. 内存管理-MRC与ARC详解

    Objective-C提供了两种内存管理机制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),为Objective-C提 ...

  5. MRC转ARC

    转载请注明出处:http://blog.csdn.net/cywn_d/article/details/18222671 1.删除所有retain,release和autorelease. 2.把原来 ...

  6. @autoreleasepool在MRC和ARC中的区别

    对于@autoreleasepool {} (1)在ARC中会销毁所有在里面创建的对象,即使你用外面的Strong指针指向他 (2)在MRC中如果有外部的强指针指向,不会销毁对象,retainCoun ...

  7. 【Bugly干货分享】iOS内存管理:从MRC到ARC实践

    Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的 ...

  8. MRC和ARC混编

    iOS5.0以后就开始可以使用ARC( Automatic Reference Counting:自动引用计数)来代替之前的MRC(Manual Reference Counting:人工引用计数). ...

  9. MRC BlOCK ARC

       /*-------------------MRC环境中-------------------------*/     //使用局部变量:a到block块中,为了在block中能够使用这个变量,将 ...

随机推荐

  1. 微信公众平台——基础配置——服务器配置:PHP版

    在自己的服务器上新建一个空白php文件,输入以下任一版本的代码,如下: 版本一: <?php $token = "dige1994"; $signature = $_GET[ ...

  2. bzoj 1017: [JSOI2008]魔兽地图DotR【树形dp+背包】

    bzoj上是一个森林啊--? dp还是太弱了 设f[i][j][k]为到点i,合成j个i并且花费k金币能获得的最大力量值,a[i]为数量上限,b[i]为价格,p[i]为装备力量值 其实这个状态设计出来 ...

  3. codeforces912E(折半搜索+双指针+二分答案)

    E. Prime Gift E. Prime Gift time limit per test 3.5 seconds memory limit per test 256 megabytes inpu ...

  4. [App Store Connect帮助]七、在 App Store 上发行(3.4)提交至“App 审核”:将构建版本从审核中移除

    若要停止“App 审核”流程,您可以将该 App 版本从 App 审核中移除.要执行此项操作,App 状态必须为下列之一: 正在等待出口合规检查 正在等待审核 正在审核 等待开发者发布 等待 Appl ...

  5. 【爬坑系列】之vxlan网络实现

    linux 内核从3.7之后就内部集成了vxlan功能,所以可以使用linux内核提供的vxlan功能,经过配置创建vxlan网络. 而从Docker自Docker Engine 1.9之后,就自带o ...

  6. Luogu P2921 在农场万圣节 【tarjan in 有向图】 By cellur925

    题目传送门 上来就想到既直接又简单的暴力方法,顺着每个房间的下一个走下去就好了,但是没想到最坏情况会达到1e5,100000的数据铁定超时. #include<cstdio> #inclu ...

  7. Luogu P1396 营救【最小生成树/二分答案/最短路】 By celur925

    题目描述 “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门…… 妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小 ...

  8. border-radius的参数

    border-radius的参数: 据w3c上的官方解释,是这样子的: border-radius: 1-4 length|% / 1-4 length|%;1-4指的是radius的四个值,leng ...

  9. SpringBoot入门-15(springboot配置freemarker使用YML)

    https://blog.csdn.net/fengsi2009/article/details/78879924 application.yml spring: http: encoding: fo ...

  10. [ZOJ1610]Count the Colors

    Description 画一些颜色段在一行上,一些较早的颜色就会被后来的颜色覆盖了. 你的任务就是要数出你随后能看到的不同颜色的段的数目. Input 每组测试数据第一行只有一个整数n, 1 < ...