zoukankan      html  css  js  c++  java
  • Convert to Objective-C ARC

    今天在进行代码走查时,竟然发现了下面这段代码:

    Bad CodeBad Code

    顿时感觉吐槽无力,虽然我反复强调内存管理问题,无非就是谁申请谁释放,利用强弱引用避免 retain-cycles,但是还是会有这样那样的问题,leaks 每次就是一片红。本来是计划等他们交易都开发完了,进行一次集体代码走查,好好给他们上一课,集中来解决内存问题。但是由于个人原因我 7 月份会离开项目组,恐怕没有时间来这么做了,所以最终还是决定将工程转成 ARC 模式。

    该项目是某行手机银行客户端,iOS 开发这块除了我,其他的所有 7 个开发人员都是项目组临时招聘的,技术参差不齐,毕竟公司招聘标准就是:便宜 + 能干事。我的职责就是负责客户端架构,公共机制的设计与实现,公共组件的封装,开发过程中的解疑。其他开发人员每人负责一两个模块的交易开发,其实无非就剩下请求数据绘界面的事了。

    其实项目开始时就打算尝试用 ARC 的,但是项目组内其他人员之前都没接触过 ARC,迫于项目进度压力也没有时间做培训,就使用大家比较熟悉的 MRR,还是太信任他们了。

    Convertion Steps

    1.将不要转成 ARC 的代码标注一下

    如开源代码 AFNetworking(因为项目需要支持 4.3,所以用的 AFNetworking 是支持 4.3 的非 ARC 版本)、GDataXML、RegexKitLite、Reachability 等,其实这些也能转,但是感觉没有必要,将这些源文件在 Build Phases / Complie Sources 中标注为-fno-objc-arc,如果之前用到了使用 ARC 的代码,现在可以将-fobjc-arc标记去掉了。

    setp1setp1

    2.工程检查

    我选择使用 Xcode5.0_DP 版本来转,之前使用 Xcode4.6 在转换过程中电脑经常会假死,或者 Xcode4.6 直接崩溃,不知道什么原因。而 Xcode5.0 默认就是 ARC 模式,我想为了能让之前的程序都转换为 ARC,它的转换工具一定比之前强化了不少。

    Xcode -> Edit -> Refactor -> Convert to Objective-C ARC…

    选择要转换的 Target,工程 target,如果有单元测试也会出现单元测试的 target,点击“Check”。

    3.解决 ARC 不允许的问题

    setp3setp3

    转换工具会自动将代码里面的 retain、release、autorelease 等操作去掉,属性中的 retain、copy、assign 转为为对应的关键字(retain、copy -> strong, assign 会根据工程是否支持 5.0 一下版本转出 weak,或 unsafe_unretained)。

    但是如果你在宏里面定义如:

    #define MB_RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; }

    转换工具是不会自动处理里面的 release 的,需要手动将[__POINTER release];去掉。(我工程里面 4201 个问题基本上都是因为这个导致的)

    此外在 CF 对象与 NS 对象之间转换的需要加上关键字__bridge,这个也需要手动来来修改。

    4.开始转换

    setp4setp4

    解决完所有的冲突,再次选择“Convert to Objective-C ARC…”,你就能看到这个界面,点击“Next”后,再次经过漫长的等待, 工具会列出了将会为了转换的代码的对照列表。默认所有出现在列表里面的文件都是选中的,你可以选在不要转换的文件,去掉对勾。确认完后,点击“Save”就完成了整个工程的转换工作, Congratulations!

    (我在完成后编译时,发现之前被我标为-fno-objc-arc的文件会有报错,原来在转换过程中工具将之前的标记都去掉了,无奈再次标记了一遍。)

    5.其他处理

    因为我们工程支持 4.3,所以 weak, __weak 关键字不能用, 可以通过宏定义将 5.0 以下时 weak 关键字定义为 unsafe_unretained:

    #if (!__has_feature(objc_arc)) || 
    (defined __IPHONE_OS_VERSION_MIN_REQUIRED && 
    __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0) || 
    (defined __MAC_OS_X_VERSION_MIN_REQUIRED && 
    __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7)
    #undef weak
    #define weak unsafe_unretained
    #undef __weak
    #define __weak __unsafe_unretained
    #endif
    

    在 ARC 模式下,使用 performSelector 方法会有编译警告:PerformSelector may cause a leak because its selector is unknown,作为有洁癖的程序员是不能容许程序中有警告的:

    #progma clang diagnostic push
    #progma clang disgnostic ignored "-Warc-performSelecotr-leaks"
    [self performSelector:@selector(mySelector:) withObject:object];
    #progma clang disgnostic pop
    

    Posted by XiaoYi_HD - 6月 19 2013
    如需转载,请注明: 本文来自 Esoft Mobile

  • 相关阅读:
    使用NPOI读取Excel表格内容并进行修改
    JSON.parse()和JSON.stringify()
    切图时图片的选择:JPG、PNG、GIF的区别
    用js把数据从一个页面传到另一个页面
    iframe中positioin:fixed失效问题
    YUV格式&像素
    JS中插入节点的方法appendChild和insertBefore的应用
    CSS的相对定位和就对定位
    CSS中的相对定位和绝对定位
    POJ-1734
  • 原文地址:https://www.cnblogs.com/tracy-e/p/3151459.html
Copyright © 2011-2022 走看看