如何mrc工程中arc兼容mrc编译arc文件

ARC与非ARC在一个项目中同时使用,1,选择项目中的Targets,选中你所要操作的Target,2,选Build Phases,在其中Complie Sources中选择需要ARC的文件双击,并在输入框中输入:-fobjc-arc,如果不要ARC则输入:-fno-objc-arc
混用没有问题,没有用ARC的代码继续坚持谁申请谁释放就好了。以前的库没有时间重写,都采用这种方法。而且不知道你用的是什么第三方代码,一般来说,现在很少有arc only的代码,大部分都是用一些宏来让代码可以同时适应arc和非arc的(用#if __has_feature(objc_arc)判断)。如果代码量不大,可以考虑自己进行改写
ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。
该机能在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 可以使用该机能。简单地理解ARC,就是通过指定的语法,让编译器(LLVM 3.0)在编译代码时,自动生成实例的引用计数管理部分代码。有一点,ARC并不是GC,它只是一种代码静态分析(Static Analyzer)工具。
ARC是编译器LLVM 3.0的新功能,而非iOS,因此ARC支持&Mac&OS&X&v10.6 v10.7 (64-bit applications) 以及 iOS&4 iOS&5. (遗憾的是,weak reference 是runtime属性,因此 不支持 iOS 4 和&Mac&OS&X&v10.6。)
你不能使用new开头的变量
ARC只对objective-c对象起作用,对于Core Foundation 之类,你仍然需要自己手动释放。
ARC的优势:1、不再需要考虑retain、release的问题,我们得以在更高的层面考虑问题,而不是纠结于什么时候释放的细节。2、zeroing-weak reference , 我们终于可以摆脱烦人的&zombies 对象,想想delegate机制,当delegate对象deallocated之后,你再向它发消息会发生什么?现在当你调用 self.delegate 时,如果它被释放,那么这个弱指针会自动变为 nil 。3、ARC给人的感觉是直接存对象到变量里面。因此之前一段不可能的代码现在也变为可能:
通过一小段代码,我们看看使用ARC前后的变化点。
@interface NonARCObject : NSObject {
NSString *
-(id)initWithName:(NSString *)
@implementation NonARCObject
-(id)initWithName:(NSString *)newName {
self = [super init];
if (self) {
name = [newName retain];
-(void)dealloc {
[name release];
[Super dealloc];
@interface ARCObject : NSObject {
NSString *
-(id)initWithName:(NSString *)
@implementation ARCObject
-(id)initWithName:(NSString *)newName {
self = [super init];
if (self) {
name = newN
我们之前使用Objective-C中内存管理规则时,往往采用下面的准则
& &生成对象时,使用autorelease
& &对象代入时,先autorelease后再retain
& &对象在函数中返回时,使用return [[object retain] autorelease];
而使用ARC后,我们可以不需要这样做了,甚至连最基础的release都不需要了。
使用ARC的好处
& &使用ARC有什么好处呢?
& &看到上面的例子,大家就知道了,以后写Objective-C的代码变得简单多了,因为我们不需要担心烦人的内存管理,担心内存泄露了
& &代码的总量变少了,看上去清爽了不少,也节省了劳动力
& &代码高速化,由于使用编译器管理引用计数,减少了低效代码的可能性
不好的地方
& &记住一堆新的ARC规则 & 关键字及特性等需要一定的学习周期
& &一些旧的代码,第三方代码使用的时候比较麻烦;修改代码需要工数,要么修改编译开关
关于第二点,由于 XCode4.2 中缺省ARC就是 ON 的状态,所以编译旧代码的时候往往有"Automatic Reference Counting Issue"的错误信息。
这个时候,可以将项目编译设置中的&Objectice-C Auto Reference Counteting&设为NO。如下所示。
如果只想对某个.m文件不适应ARC,可以只针对该类文件加上 -fno-objc-arc 编译FLAGS,如下图。
ARC基本规则
& & retain, release, autorelease, dealloc由编译器自动插入,不能在代码中调用
& & dealloc虽然可以被重载,但是不能调用[super dealloc]
由于ARC并不是GC,并需要一些规则让编译器支持代码插入,所以必须清楚清楚了这些规则后,才能写出健壮的代码。
Objective-C对象
ObjectiveC中的对象,有强参照(Strong reference)和弱参照(Weak reference)之分,当需要保持其他对象的时候,需要retain以确保对象引用计数加1。对象的持有者(owner)只要存在,那么该对象的强参照就一直存在。
对象处理的基本规则是
 &只要对象的持有者存在(对象被强参照),那么就可以使用该对象
& & 对象失去了持有者后,即被破弃
强参照 (Strong reference)
(s1)firstName作为&natsu&字符串对象的最初持有者,是该NSString类型对象的Strong reference。
(s2)这里将firstName代入到aName中,即aName也成为了@&natsu&字符串对象的持有者,对于该对象,aName也是Strong reference。(s3)这里,改变firstName的内容。生成新的字符串对象&maki&。这时候firstName成为&maki&的持有者,而@&natsu&的持有者只有aName。每个字符串对象都有各自的持有者,所以它们都在内存中都存在。(s4)追加新的变量otherName, 它将成为@&maki&对象的另一个持有者。即NSString类型对象的Strong reference。(s5)将otherName代入到aName,这时,aName将成为@&maki&字符串对象的持有者。而对象@&natsu&已经没有持有者了,该对象将被破弃。
弱参照 (Weak reference)
(w1)与强参照方式同样,firstName作为字符串对象@&natsu&的持有者存在。即是该NSString类型对象的Strong reference。
(w2)使用关键字__weak,声明弱参照weakName变量,将firstName代入。这时weakName虽然参照@&natsu&,但仍是Weak reference。即weakName虽然能看到@&natsu&,但不是其持有者。(w3)firstName指向了新的对象@&maki&,成为其持有者,而对象@&natsu&因为没有了持有者,即被破弃。同时weakName变量将被自动代入nil。引用关键字
ARC中关于对象的引用参照,主要有下面几关键字。使用strong, weak, autoreleasing限定的变量会被隐式初始化为nil。
变量声明缺省都带有__strong关键字,如果变量什么关键字都不写,那么缺省就是强参照。
上面已经看到了,这是弱参照的关键字。该概念是新特性,从 iOS 5/ Mac OS X 10.7 开始导入。由于该类型不影响对象的生命周期,所以如果对象之前就没有持有者,那么会出现刚创建就被破弃的问题,比如下面的代码。
NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]];
NSLog(@"string: %@", string); //此时 string为空
如果编译设定OS版本 Deployment Target 设定为这比这低的版本,那么编译时将报错(The current deployment target does not support automated __weak references),这个时候,我们可以使用下面的__unsafe_unretained。
弱参照还有一个特征,即当参数对象失去所有者之后,变量会被自动付上nil (Zeroing)。
__unsafe_unretained
该关键字与__weak一样,也是弱参照,与__weak的区别只是是否执行nil赋值(Zeroing)。但是这样,需要注意变量所指的对象已经被破弃了,地址还还存在,但内存中对象已经没有了。如果还是访问该对象,将引起「BAD_ACCESS」错误。
__autoreleasing
该关键字使对像延迟释放。比如你想传一个未初始化的对像引用到一个方法当中,在此方法中实例化此对像,那么这种情况可以使用__autoreleasing。他被经常用于函数有值参数返回时的处理,比如下面的例子。
- (void) generateErrorInVariable:(__autoreleasing NSError **)paramError {
*paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary];
NSError *error =
[self generateErrorInVariable:&error];
NSLog(@"Error = %@", error);
又如函数的返回值是在函数中申请的,那么希望释放是在调用端时,往往有下面的代码。
-(NSString *)stringTest
NSString *retStr = [NSString stringWithString:@"test"];
return [[retStr retain] autorelease];
// 使用ARC
-(NSString *)stringTest
__autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"];
return retS
即当方法的参数是id*,且希望方法返回时对象被autoreleased,那么使用该关键字。
今天,我们看到了基本的ARC使用规则
& & 代码中不能使用retain, release, retain, autorelease
& & 不重载dealloc(如果是释放对象内存以外的处理,是可以重载该函数的,但是不能调用[super dealloc])
& & 不能使用NSAllocateObject, NSDeallocateObject
& & 不能在C结构体中使用对象指针
& & id与void *间的如果cast时需要用特定的方法(__bridge关键字)
& & 不能使用NSAutoReleasePool、而需要@autoreleasepool块
& & 不能使用&new&开始的属性名称 (如果使用会有下面的编译错误&Property&s synthesized getter follows Cocoa naming convention for returning &owned& objects&)
Part 1:Part 2:Apple 文档
阅读(...) 评论() 上传我的文档
 下载
 收藏
毕业于医学院校,在医院工作,有相对丰富的护理经验
 下载此文档
正在努力加载中...
ARC和MRC 兼容的单例模式(烟台杰瑞教育原创)
下载积分:1500
内容提示:ARC和MRC 兼容的单例模式(烟台杰瑞教育原创)
文档格式:DOCX|
浏览次数:0|
上传日期: 03:09:16|
文档星级:
该用户还上传了这些文档
ARC和MRC 兼容的单例模式(烟台杰瑞教育原创)
官方公共微信下次自动登录
关注移动互联网和移动APP开发工具、开发框架、测试工具、微信开发、Android源码、Android开源类库以及各种开源组件的IT科技网站
现在的位置:
iOS开发——深入解析iOS内存管理机制ARC和MRC
本文重点讲述了iOS的内存管理机制ARC和MRC,这是很多iOS程序员在面试时会经常被问到的问题,涉及到ARC和MRC的概念、工作原理、使用场景以及在遇到内存泄露等问题时如何解决,现在整理出来分享给广大的iOS程序员兄弟们,希望给他们的开发工作带来帮助。
-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  iAronTalk Blog opens.
  Even if the present, the match does not stop changes the page.
-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Part 1:面试问题集(积累-ing)
=-=-01.ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?
    Answer:atomic,readwrite,strong(对象),assgin(基本数据类型)。
=-=-02.objc中,ARC/MRC分别都是如何进行内存管理的?
    Answer:参考下文。
Part 2:知识点小节
程序运行过程中系统会创建大量的对象,跟大多数的高级语言一样,在ObjC中对象存储在堆中,系统并不会自动释放堆中的内存,需要注意的时基本类型是由系统自己管理的,放在栈上。如果一个对象创建并使用后没有得到及时释放那么就会占用大量内存,内存的积累使得系统卡慢,严重程序会直接崩溃掉。其他高级语言如C#、Java都是通过垃圾回收来(GC)解决这个问题的,但在OjbC中并没有类似的垃圾回收机制,因此苹果想出了采用引用计数这个概念来对内存中的对象进行管理,在SDK4.0之前使用的是MRC,即手动内存管理,在4.0之后苹果引入了ARC(自动内存管理),大大的节省了开发人员的时间,以往劳神费力的手动内存管理时代渐渐远去,但在遇到底层Core Foundation对象就需要自己手工管理引用计数了。
关于内存管理:“程序运行时,开辟的内存空间。使用它,释放它”的过程,写的好的程序尽可能少使用内存。在Objective-C中,内存管理被看做是:“在很多数据、代码下,分配受限内存资源所有权方法”。当你依据这个指南完成你的程序时,你将获得“通过 显式管理对象的命周期,不使用的时候释放他们,来管理程序内存”的知识。
纵观整个iOS开发中的内存管理,深层次上是对内存中对象的合理保留和释放,但是浅层次上无疑是引用计数世界。我们不曾直接的对内存进行任何操作,而一切的操作都是起于引用计数,止于引用计数。无论ARC和MRC,都是对引用计数的不同操作而已。
=-=-Section A:Objective-中的MRC(MannulReference Counting)
**01.在MRC的内存管理模式下,与对变量的管理相关的方法有:retain,release和autorelease。retain和release方法操作的是引用记数,当引用记数为零时,便自动释放内存。并且可以用NSAutoreleasePool对象,对加入自动释放池(autorelease调用)的变量进行管理,当drain时回收内存。
  (1)retain,该方法的作用是将内存数据的所有权附给另一指针变量,引用数加1,即retainCount+= 1;
  (2)release,该方法是释放指针变量对内存数据的所有权,引用数减1,即retainCount-= 1;
  (3)autorelease,该方法是将该对象内存的管理放到autoreleasepool中。
  示例代码:
  //假设Person为预定义的类
   Person* person = [[Person alloc] init];
   [person retain];//此时引用记数+1,现为2
  [person release];//person释放对内存数据的所有权 引用记数-1,现为0;
   [person run];//出现野指针,此时内存已释放。
**02.//autoreleasepool 的使用 在MRC管理模式下,
Person* person = [[Person alloc] init];
[person autorelease];//由autoreleasepool来管理其内存的释放
(nonatomic/atomic,retain/assign/copy, readonly/readwrite) Number*
  1)nonatomic/atomic,表示该属性是否是对多线程安全的,是不是使用线程锁,默认为atomic,
  2)retain/assign/copy,是有关对该属性的内存管理的,
assign"is the default. In the setter that is created by @synthesize, the value willsimply be assigned to the attribute, don’t operate the retain count. Myunderstanding is that "assign" should be used for non-pointer attributes.
"retain"is needed when the attribute is a pointer to an object. The setter generated
will retain (aka add a retain count) the object. You will need torelease the object when you are finished with it.
"copy"is needed when the object is mutable. Use this if you need the value of theobject as it is at this moment, and you don't want that value to reflect anychanges made by other owners of the object. You will need to release the objectwhen you are finished with it because you are retaining the copy.
  (3)readwrite /readonly -"readwrite" is the default. When you @synthesize, both a getter and asetter will be created for you. If you use "readonly", no setter willbe created. Use it for a value you don't want to ever change after the instantiationof the object.
=-=-Section B:Objective-c语言中的ARC(AutomaticReference Counting)
**01.在ARC中与内存管理有关的标识符,可以分为变量标识符和属性标识符,对于变量默认为__strong,而对于属性默认为unsafe_unretained。也存在    
  autoreleasepool。
对于变量的标识符有:
  1) __strong,is the default. An object remains “alive” as long as there is a strong pointerto it.
  2) __weak,specifies a reference that does not keep the referenced object alive. A weakreference is set to nil when there are no strong references to the object.
  3)__unsafe_unretained,specifies a reference that does not keep the referenced object alive and is notset to nil when there are no strong references to the object. If the object itreferences is deallocated, the pointer is left dangling.
  4)__autoreleasing,is used to denote arguments that are passed by reference (id *) and areautoreleased on return,managedby Autoreleasepool.
**02.对于变量标识符的用法:
  __strong Person* person = [[Person alloc]init];
  在ARC内存管理模式下,其属性的标识符存在以下几种:
**03.@property (nonatomic/atomic, assign/retain/strong/weak/unsafe_unretained/copy,readonly/readwrite) Number*//默认为         
  unsafe_unretained
其中assign/retain/copy与MRC下property的标识符意义相同,strong类似与retain,assign类似于unsafe_unretained,strong/weak/unsafe_unretained与ARC下变量标识符意义相同,只是一个用于属性的标识,一个用于变量的标识(带两个下划短线__)。所列出的其他的标识符与MRC下意义相同。
  (1)对于assign,你可以对标量类型(如int)使用这个属性。你可以想象一个float,它不是一个对象,所以它不能retain、copy。
  (2)对于copy,指定应该使用对象的副本(深度复制),前一个值发送一条release消息。基本上像retain,但是没有增加引用计数,是分配一块新的内存来放置它。
特别适用于NSString,如果你不想改变现有的,就用这个,因为NSMutableString,也是NSString。
**04.对于Core Foundation与objective-cObject进行交换时,需要用到的ARC管理机制有:
  1) (__bridge_transfer&NSType&) op oralternatively CFBridgingRelease(op) isused to consume a retain-count of a CFTypeRef whiletransferring it over to ARC. This could also be represented by id someObj =(__bridge &NSType&) CFRelease(op);
  2) (__bridge_retained&CFType&) op oralternatively CFBridgingRetain(op) isused to hand an NSObject overto CF-land while giving it a +1 retain count. You should handle a CFTypeRefyoucreate this way the same as you would handle a result of CFStringCreateCopy().This could also be represented by CFRetain((__bridge CFType)op); CFTypeRef someTypeRef =(__bridge CFType)
  3) __bridge justcasts between pointer-land and Objective-C object-land. If you have noinclination to use the conversions above, use this one.
=-=-Section C:Objectiv使用分析工具来调试内存问题
在编译时候找出代码的问题。使用Xcode内嵌的Clang Static Analyzer 。
如果内存管理的问题仍然发生,还有其他的工具和技术,你可以用它来识别和诊断问题。
1.多数工具和技术都在TN2239中有描述,iOS Debugging Magic 特别是NSZombie来帮助找到过度释放对象。
2.使用Instruments来追踪引用计数事件并找到内存泄露。( 参考 Collecting Data on Your App)
本文到此结束,希望给朋友们带来帮助。
【上篇】【下篇】}

我要回帖

更多关于 mrc转arc 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信