1. ARC & MRC 混合开发

在项目开发中,遇到使用MRC开发的第三方库怎么办?

例如:ASI

1> 尝试使用Xcode的转换工具(失败率比较高)

2> 在编译选项中,为MRC的程序添加-fno-objc-arc标记,表明在编译时,该文件使用MRC编译

备注:

(1) 演示中使用的RegexKitLite还需要导入libicucore.dylib动态库

(2) 如果要在MRC项目中添加ARC的文件,可以使用 -fobjc-arc 标记即可

3> 将MRC的第三方库直接编译成静态库使用

注意:在编译静态库时,不能添加动态库引用

说明:

RegexKitLite是对NSString添加的正则表达式分类

在项目中,如果使用的静态库中包含分类,则需要在Other Link Flag中添加 -ObjC选项

什么是ARC?

Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化。ARC是新的LLVM 3.0编译器的一项特性,使用ARC,可以说一举解决了广大iOS开发者所憎恨的手动内存管理的麻烦。

ARC机制

学习ARC很简单,在MRC时代你需要自己retain一个想要保持的对象,而现在不需要了。现在唯一要做的是用一个指针指向这个对象,只要指针没有被置空,对象就会一直保持在堆上。当将指针指向新值时,原来的对象会被release一次。这对实例变量,sunthesize的变量或者局部变量都是适用的。比如


  1. NSString *firstName = self.textField.text;

firstName现在指向NSString对象,这时这个对象(textField的内容字符串)将被hold住。比如用字符串@“OneV”作为例子,这个时候firstName持有了@”OneV”。

当然,一个对象可以拥有不止一个的持有者(这个类似MRC中的retainCount>1的情况)。在这个例子中显然self.textField.text也是@“OneV”,那么现在有两个指针指向对象@”OneV”(被持有两次,retainCount=2,其实对NSString对象说retainCount是有问题的,不过anyway~就这个意思而已.)。

过了一会儿,也许用户在textField里输入了其他的东西,那么self.textField.text指针显然现在指向了别的字符串,比如@“onevcat”,但是这时候原来的对象已然是存在的,因为还有一个指针firstName持有它。现在指针的指向关系是这样的:

只有当firstName也被设定了新的值,或者是超出了作用范围的空间(比如它是局部变量但是这个方法执行完了或者它是实例变量但是这个实例被销毁了),那么此时firstName也不再持有@“OneV”,此时不再有指针指向@”OneV”,在ARC下这种状况发生后对象@”OneV”即被销毁,内存释放。

类似于firstName和self.textField.text这样的指针使用关键字”strong”进行标志,它意味着只要该指针指向某个对象,那么这个对象就不会被销毁。反过来说,ARC的一个基本规则即使,只要某个对象被任一strong指针指向,那么它将不会被销毁。如果对象没有被任何strong指针指向,那么就将被销毁。在默认情况下,所有的实例变量和局部变量都是strong类型的。可以说strong类型的指针在行为上和MRC时代retain的property是比较相似的。

既然有”strong”,那肯定有”weak”咯~weak类型的指针也可以指向对象,但是并不会持有该对象。比如:


  1. __weak NSString *weakName = self.textField.text

得到的指向关系是:

这里声明了一个weak的指针weakName,它并不持有@“onevcat”。如果self.textField.text的内容发生改变的话,根据之前提到的“只要某个对象被任一strong指针指向,那么它将不会被销毁。如果对象没有被任何strong指针指向,那么就将被销毁”原则,此时指向@“onevcat”的指针中没有strong类型的指针,@”onevcat”将被销毁。同时,在ARC机制作用下,所有指向这个对象的weak指针将被置为nil。这个特性相当有用,相信无数的开发者都曾经被指针指向已释放对象所造成的EXC_BAD_ACCESS困扰过,使用ARC以后,不论是strong还是weak类型的指针,都不再会指向一个dealloced的对象,从根源上解决了意外释放导致的crash。

不过在大部分情况下,weak类型的指针可能并不会很常用。比较常见的用法是在两个对象间存在包含关系时:对象1有一个strong指针指向对象2,并持有它,而对象2中只有一个weak指针指回对象1,从而避免了循环持有。一个常见的例子就是oc中常见的delegate设计模式,viewController中有一个strong指针指向它所负责管理的UITableView,而UITableView中的dataSource和delegate指针都是指向viewController的weak指针。可以说,weak指针的行为和MRC时代的assign有一些相似点,但是考虑到weak指针更聪明些(会自动指向nil),因此还是有所不同的。细节的东西我们稍后再说。

注意类似下面的代码似乎是没有什么意义的:


  1. __weak NSString *str = [[NSString alloc] initWithFormat:…];
  2. NSLog(@"%@",str); //输出是"(null)"

由于str是weak,它不会持有alloc出来的NSString对象,因此这个对象由于没有有效的strong指针指向,所以在生成的同时就被销毁了。如果我们在Xcode中写了上面的代码,我们应该会得到一个警告,因为无论何时这种情况似乎都是不太可能出现的。你可以把weak换成strong来消除警告,或者直接前面什么都不写,因为ARC中默认的指针类型就是strong。

property也可以用strong或weak来标记,简单地把原来写retain和assign的地方替换成strong或者weak就可以了。


  1. @property (nonatomic, strong) NSString *firstName;
  2. @property (nonatomic, weak) id  delegate;

ARC可以为开发者节省很多代码,使用ARC以后再也不需要关心什么时候retain,什么时候release,但是这并不意味你可以不思考内存管理,你可能需要经常性地问自己这个问题:谁持有这个对象?

比如下面的代码,假设array是一个NSMutableArray并且里面至少有一个对象:


  1. id obj = [array objectAtIndex:0];
  2. [array removeObjectAtIndex:0];
  3. NSLog(@"%@",obj);

在MRC时代这几行代码应该就挂掉了,因为array中0号对象被remove以后就被立即销毁了,因此obj指向了一个dealloced的对象,因此在NSLog的时候将出现EXC_BAD_ACCESS。而在ARC中由于obj是strong的,因此它持有了array中的首个对象,array不再是该对象的唯一持有者。即使我们从array中将obj移除了,它也依然被别的指针持有,因此不会被销毁。

关于ARC的介绍和ARC与MRC混编解决的更多相关文章

  1. ARC、MRC混编

    Xcode5之后,新建iOS工程,默认都是ARC模式,但是有时候我们的项目中需要用到一些第三方框架,我们下载下来却发现是非ARC的,这时候我们需要进行ARC和MRC混编. 第一种方式: Edit-&g ...

  2. ARC和MRC混编

    在targets的build phases选项下Compile Sources下选择要不使用arc编译的文件,双击它,输入 -fno-objc-arc 即可 MRC工程中也可以使用ARC的类.方法如下 ...

  3. iOS ARC和MRC混编

    如果一个工程为MRC,其中需要添加ARC的文件: 选择target  ->  build phases  ->  compile sources  ->单击ARC的文件将compil ...

  4. Xcode中实现ARC和MRC混编

    1.在Xcode中打开项目文件 2.选中项目名称 3.在右侧选择build phass 选项卡 4.选择 complite source 选项 5.选择要支持MRC编译的.m文件,双击 6.在弹出的框 ...

  5. iOS ARC与MRC混编的一些解决方法

    1. ARC & MRC 混合开发 在项目开发中,遇到使用MRC开发的第三方库怎么办? 例如:ASI 1> 尝试使用Xcode的转换工具(失败率比较高) 2> 在编译选项中,为MR ...

  6. ios-实现ARC与MRC混编

    选择target -> build phases -> compile sources -> 用ARC的文件将compiler flags设置为:-fobjc-arc,用MRC的文件 ...

  7. object-c 的ARC 问答/介绍

    原文:http://blog.csdn.net/kmyhy/article/details/8895606 概念" Clangstatic analyzer "是一个非常有用的查找 ...

  8. ARC初步介绍

    [转载自 http://onevcat.com/2012/06/arc-hand-by-hand/] 手把手教你ARC——iOS/Mac开发ARC入门和使用 Revolution of Objecti ...

  9. 手把手教你ARC——iOS/Mac开发ARC入门和使用

    转载自:http://www.onevcat.com/2012/06/arc-hand-by-hand/ 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流和 ...

随机推荐

  1. 3.关于QT中的MainWindow窗口,MenuBar,ToolBar,QuickTip等方面的知识点

     1 新建一个空Qt项目 编写12MainWindow.pro HEADERS += \ MyMainWindow.h \ MyView.h SOURCES += \ MyMainWindow.c ...

  2. python 子包引用父包和其他子包

    python 子包引用父包和其他子包 python引用子目录很简单, 里面放个__init__.py就可以了. 如何在子目录里面引用其他目录(父目录,爷目录和同辈分目录)呢? 例如: python有项 ...

  3. SQL Server2012 AlwaysOn 无法将数据库联接到可用性组 针对主副本的连接未处于活动状态

    在配置alwayson的可用性组时遇到如下截图中的错误,这里的服务器86是作为副本数据库服务器的. 解决该问题只需将SQL服务的运行账号改成管理员,并且打开防火墙中的5022端口(该端口号可在可用性组 ...

  4. JSP实现界面的自动跳转的几种方式

    下面来谈一谈在jsp中实现的几种界面自动跳转的方法. 使用JavaScript脚本 <html> <script language=javascript> function o ...

  5. matlab中 mcc/mbuild/mex 区别

    mcc 的作用是将 .m文件编译为 c/c++动态链接库文件,使你可以在 c/c++程序中使用 matlab的一些函数功能.mcc 也可以将.m文件编译为exe可执行文件. mex 的作用是将 c/c ...

  6. MO_GLOBAL - EBS R12 中 Multi Org 设计的深入研究 (3)

    这是多组织访问的第三篇文章,翻译自Anil Passi的MO_GLOBAL-Dive into R12 Multi Org Design 我希望你已经读了文章 EBS R12 中的 Multi Org ...

  7. JAVA内部类_1

    使用内部类的原因: (1)可以访问该类定义所在作用域中的数据,包括私有数据. (2)可以对同一个包中的其它类隐藏起来. (3)当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷. 下面 ...

  8. Android解析中国天气接口JSon数据,应用于天气查询!

    android解析Json数据是比较常见的一种操作.也是客户端和服务器进行数据交互的桥梁.下面就来看一看在android中解析JSon数据的方法吧. 首先要想获得Json数据,就必须访问相关的网络接口 ...

  9. 4.6、Libgdx线程介绍

    (原文:http://www.libgdx.cn/topic/48/4-6-libgdx%E7%BA%BF%E7%A8%8B%E4%BB%8B%E7%BB%8D) 所有的ApplicationList ...

  10. (六十一)Xcode的git版本控制

    打开终端 1.为项目添加git: 首先到达项目的根目录内部,输入git init,初始化一个空的代码仓库(隐藏文件.get). 接下来使用git add . --all .表达把当前目录及子目录中的文 ...