`
miss大为
  • 浏览: 82325 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

iPhone开发之 ARC是什么

阅读更多
相关链接:http://blog.csdn.net/diyagoanyhacker/article/details/7069889
         http://www.yifeiyang.net/development-of-the-iphone-simply-1/

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前后的变化点。
@interface NonARCObject : NSObject {
    NSString *name;
}
-(id)initWithName:(NSString *)name;
@end

@implementation NonARCObject
-(id)initWithName:(NSString *)newName {
    self = [super init];
    if (self) {
        name = [newName retain];
    }
    return self;
}

-(void)dealloc {
    [name release];
    [Super dealloc];
}
@end

@interface ARCObject : NSObject {
    NSString *name;
}
-(id)initWithName:(NSString *)name;
@end

@implementation ARCObject
-(id)initWithName:(NSString *)newName {
    self = [super init];
    if (self) {
        name = newName;
    }
    return self;
}
@end

我们之前使用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)
接下来我们来看看弱参照 (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
变量声明缺省都带有__strong关键字,如果变量什么关键字都不写,那么缺省就是强参照。

__weak
上面已经看到了,这是弱参照的关键字。该概念是新特性,从 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 = nil;
    [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 retStr;
}

即当方法的参数是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”)
分享到:
评论

相关推荐

    如何学好Iphone开发

    学习iPhone开发是一个系统而全面的过程,它涉及到编程基础、开发工具、框架掌握等多个方面。文章以《如何学好iPhone开发》为主题,详细阐述了学习iPhone游戏开发所需的基础知识、推荐的学习资源、开发工具的运用、...

    iphone开发应用之计算器

    在iOS平台上,开发一款应用程序,比如“iPhone开发应用之计算器”,通常涉及到多个技术层面和步骤。这个特定的应用,名为"CuteCal",已经成功上线并可在App Store中找到,这表明开发者已经完成了从设计到发布的整个...

    iPhone 开发例子2

    在本主题"iPhone 开发例子2"中,我们将深入探讨iPhone应用开发的相关知识,这个压缩包文件包含了2008年11月19日的示例代码,旨在为正在学习iPhone开发的初学者提供实践指导。以下是这些示例可能涵盖的一些关键知识点...

    iPhone开发基础教程&Objective-C.2.0程序设计

    在IT行业中,iOS应用开发是一项高需求的技能,而学习这一领域的基础往往从掌握Objective-C.2.0和iPhone开发开始。"iPhone开发基础教程&Objective-C.2.0程序设计"是为初学者量身定制的学习资源,旨在帮助他们踏入这个...

    iPhone开发快速上手

    标题“iPhone开发快速上手”暗示我们将探讨如何快速入门iOS应用开发,特别是针对iPhone设备。这里的关键知识点包括: 1. **Swift编程语言**:iOS开发主要使用Swift,这是一种由Apple推出的开源编程语言。Swift语法...

    iPhone开发基础教程

    《iPhone开发基础教程》是一本面向初学者的iOS应用开发指南,由(美)Dave Mark和Jeff LaMarche合作撰写,于2009年4月由人民邮电出版社出版。这本书深入浅出地介绍了如何使用苹果的Xcode集成开发环境(IDE)以及...

    iphone 开发

    《iPhone开发》是一本专注于Objective-C编程语言及其在iPhone应用开发中的实践的书籍。Objective-C是苹果公司开发的C语言的扩展,它为C语言增加了面向对象编程的特性,是开发Mac OS X和iOS应用程序的核心语言。这...

    《iPhone开发秘籍_第2版》PDF版本下载.txt

    根据提供的文件信息,我们可以推断出这是一本关于iPhone应用开发的专业书籍——《iPhone开发秘籍_第2版》,并且提供了该书PDF版本的下载链接。下面将对这本书可能涉及的关键知识点进行详细的介绍。 ### 一、iOS开发...

    objc iphone开发基础pdf

    除此之外,学习iPhone开发还需要理解内存管理和ARC(Automatic Reference Counting)机制,以及多线程编程,包括GCD(Grand Central Dispatch)和NSOperationQueue。网络编程也是必不可少的一部分,Objective-C提供...

    谢伟-基于iPhone开发实践

    ### 基于iPhone开发实践 #### 演讲者简介 本次分享由博看文思CTO谢伟(Wayne)主讲。谢伟是一位热爱编程的技术专家,他在iPhone开发领域有着丰富的经验和深刻的见解。 #### 博看科技介绍 博看科技是一家专注于3G...

    iphone4开发入门

    《iPhone4开发入门》这本书是针对初学者的一本经典教程...通过这本书,你将不仅能够学习到Objective-C语言和iOS SDK的基本用法,还能了解到开发iPhone 4应用的各种技巧和最佳实践,从而为你的iOS开发之旅打下坚实基础。

    iPhone开发基础教程源码

    在本教程中,我们将深入探讨"iPhone开发基础教程源码",这是一份全面的教育资源,旨在帮助初学者掌握iOS应用开发的基础知识。这个压缩包包含的文件名为"Beginning iPhone Development Projects Oct 12 2009",暗示了...

    iphone开发基础教程

    《iPhone开发基础教程》是一本面向初学者的iOS应用程序开发指南,主要涵盖了iPhone应用开发的基础知识和关键技能。尽管我们目前只有第一、第三和第八章节的内容,但这些章节已经能够帮助读者建立对iOS开发的基本理解...

    iphone 开发基础教程 源代码

    《iPhone开发基础教程》源代码解析 在移动应用开发领域,iOS平台凭借其稳定性和丰富的功能,吸引了大量的开发者。对于想要踏入这个领域的初学者来说,掌握iPhone应用开发的基础至关重要。本教程将围绕“Beginning ...

    iPhone开发实战.pdf

    《iPhone开发实战》这本书是为想要踏入iOS应用开发领域的初学者和有志于提升技能的开发者精心准备的一份宝贵资源。iOS开发,尤其是针对iPhone的应用程序设计,是苹果生态系统中的重要组成部分,它涉及到Apple的iOS...

    iPhone开发入门教程

    ### iPhone开发入门教程知识点解析 #### 一、教程概述与背景 - **发布时间**:2008年5月2日。 - **发布者**:Apple Inc.。 - **版权说明**:本教程受版权保护,未经苹果公司事先书面许可,不得以任何形式或方式...

    iphone xcode 手机开发

    在iPhone开发中,Xcode是主要的集成开发环境(IDE),它包含了开发Objective-C应用所需的一切工具,包括编译器、调试器、模拟器以及Interface Builder等可视化设计工具。通过Xcode,开发者可以创建基于window-based...

    最权威的iphone开发资料

    标题中的“最权威的iPhone开发资料”表明了这个压缩包包含的是关于iPhone应用程序开发的专业文献。这些资源可能来自知名出版商或业界专家,为开发者提供深入的指导和知识。 描述中提到“含中文和英文资料”,这暗示...

    iphone开发教程1

    【iPhone开发教程1:入门与基础】 iPhone开发是iOS应用开发的一部分,主要使用Apple的Swift编程语言和Xcode集成开发环境(IDE)进行。斯坦福大学的教程是全球知名的教育资源,为开发者提供深入且系统的学习路径,...

Global site tag (gtag.js) - Google Analytics