`

iPhone开发之深入浅出 (1) — ARC是什么

 
阅读更多

来源: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前后的变化点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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"的错误信息。


ARC_error

这个时候,可以将项目编译设置中的“Objectice-C Auto Reference Counteting”设为NO。如下所示。


ARC_Xcode

如果只想对某个.m文件不适应ARC,可以只针对该类文件加上 -fno-objc-arc 编译FLAGS,如下图。


ARC_Xcode

ARC基本规则

  • retain, release, autorelease, dealloc由编译器自动插入,不能在代码中调用
  • dealloc虽然可以被重载,但是不能调用[super dealloc]

由于ARC并不是GC,并需要一些规则让编译器支持代码插入,所以必须清楚清楚了这些规则后,才能写出健壮的代码。

Objective-C对象

ObjectiveC中的对象,有强参照(Strong reference)和弱参照(Weak reference)之分,当需要保持其他对象的时候,需要retain以确保对象引用计数加1。对象的持有者(owner)只要存在,那么该对象的强参照就一直存在。

对象处理的基本规则是
  • 只要对象的持有者存在(对象被强参照),那么就可以使用该对象
  • 对象失去了持有者后,即被破弃
强参照 (Strong reference)


ARC_outline_strong

(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) 的使用方式。


ARC_outline_weak

(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 开始导入。由于该类型不影响对象的生命周期,所以如果对象之前就没有持有者,那么会出现刚创建就被破弃的问题,比如下面的代码。

1
2
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。他被经常用于函数有值参数返回时的处理,比如下面的例子。

1
2
3
4
5
6
7
8
9
10
11
- (void) generateErrorInVariable:(__autoreleasing NSError **)paramError {
    ....
    *paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary];
}

....
{
    NSError *error = nil;
    [self generateErrorInVariable:&error];
    NSLog(@"Error = %@", error);
}

又如函数的返回值是在函数中申请的,那么希望释放是在调用端时,往往有下面的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-(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”)

今后,我们将更加深入ARC,学习其更多的特性。

分享到:
评论

相关推荐

    《iPhone应用程序开发攻略之深入浅出Objective-C 2.0》.(王志刚).[PDF]&ckook

    《iPhone应用程序开发攻略之深入浅出Objective-C 2.0》是王志刚撰写的一本专为iOS开发者设计的教程,旨在帮助读者掌握Objective-C 2.0编程语言,从而能够开发高质量的iPhone应用程序。Objective-C是苹果公司开发的...

    深入浅出iphone编程 (headfirst iphone development)11 chapter

    《深入浅出iPhone编程》是Head First系列中的一本专为初学者设计的iOS开发教程,专注于iPhone应用的开发。本书的第11章在前10章的基础上,继续深入探讨iOS开发的关键技术和实践,旨在帮助读者理解并掌握iPhone应用...

    深入浅出讲objective-c

    "深入浅出讲Objective-c"的文档很可能涵盖了这些内容,并可能包含更多关于类设计、异常处理、调试技巧等实际开发中的细节。通过学习这份文档,初学者可以系统地掌握Objective-C的基础知识,并逐步进入iOS和macOS应用...

    iPhone开发基础教程

    这本书深入浅出地介绍了如何使用苹果的Xcode集成开发环境(IDE)以及Objective-C编程语言来构建iPhone应用程序。 首先,iOS平台的基础知识是学习iPhone开发的起点。iOS是由苹果公司开发的操作系统,主要运行在...

    iphone 开发

    首先,本书深入浅出地讲解了Objective-C的基础知识,包括语法结构、类、对象、消息传递等核心概念。Objective-C是基于Smalltalk的面向对象语言,它引入了“协议”(protocols)和“类别”(categories)等独特特性,...

    iPhone4开发入门 Beginning iPhone 4 +源代码.zip

    这本书由David Mark、Jeff LaMarche和Jack Nutting三位专家撰写,他们深入浅出地讲解了如何使用iOS SDK进行应用程序开发。书中不仅包含了理论知识,还有丰富的实践案例,旨在帮助读者快速掌握iOS编程技能。 首先,...

    iphone 开发Objective-C

    ### Objective-C基础教程:iPhone开发必备 ...对于希望从事iOS开发的专业人士来说,《Objective-C基础教程》是一本不可多得的好书,它不仅深入浅出地讲解了Objective-C的各种特性,还通过丰富的示例帮助读者快速上手。

    iPhone5与iPad开发必备基础教程【英文原版 PDF】

    《iPhone5与iPad开发必备基础教程》是一本专为初学者设计的iOS开发指南,英文原版PDF形式提供了深入浅出的讲解。本书的核心目标是帮助读者掌握在iPhone5和iPad上进行应用开发的基本技能,尤其针对iOS 5版本进行了...

    iphone基础编程2

    斯坦福大学的这门课程以其深入浅出的教学方式而闻名,即使是对于编程新手来说也十分友好。讲义以英文编写,但用词清晰,概念解释详尽,使得复杂的编程概念变得易于理解。这是一份宝贵的教育资源,它不仅涵盖了基本的...

    iphone基础编程讲义6

    《iPhone基础编程讲义6》是一份源自斯坦福大学的教育资源,主要针对初学者,以英文形式深入浅出地介绍了iOS应用开发的基础知识。这份讲义涵盖了iPhone编程的关键概念和技术,帮助开发者逐步掌握构建iPhone应用的技能...

    iPhone 斯坦福大学教学课件

    斯坦福大学的iPhone编程课程以其深入浅出的讲解闻名,即使对于英文不甚精通的学习者来说,也能轻松理解其中的知识点。本课程主要围绕Objective-C语言和iOS应用开发的核心概念展开,旨在帮助开发者掌握创建iPhone应用...

    Learn Objective-C on the mac

    《在Mac上学习Objective-C》是一本针对iPad和iPhone应用开发入门的经典教程,它深入浅出地介绍了Objective-C这门编程语言,以及如何利用它在苹果的生态系统中创建应用程序。Objective-C是苹果平台的主要开发语言,是...

    iOS_5_Programming_Cookbook.pdf

    这本书深入浅出地介绍了如何利用Objective-C语言和Xcode开发工具来构建功能丰富的iPhone和iPad应用程序。书中的内容丰富多样,涵盖了从基本的UI设计到复杂的网络编程的各种技巧和解决方案。 在iOS 5的开发环境中,...

    object-c基础教程

    本教程将深入浅出地介绍Object-C的基础知识,帮助初学者快速入门。 ### 一、Object-C简介 Object-C是在C语言基础上扩展的,增加了面向对象的特性,如类、继承、消息传递等。它的语法与Smalltalk非常相似,但同时也...

    一步一步iOS5编程第三版

    《一步一步iOS5编程 第三版》是一本专为iOS开发初学者设计的详细教程,它以iOS5为核心,深入浅出地介绍了iOS平台上的应用程序开发技术。这本书旨在帮助读者掌握苹果公司的移动操作系统上的编程技能,无论是对iOS设备...

    Objective-C.2.0程序设计

    《Objective-C.2.0程序设计》是一本深入浅出介绍Objective-C编程语言的经典教材,尤其适合初学者作为入门指南。Objective-C是一种面向对象的编程语言,由Stepstone公司在1980年代开发,后来被苹果公司收购并进一步...

    GNUstep API函数速查手册

    这本手册深入浅出地介绍了GNUstep中的各种API函数,对于熟悉iOS开发的程序员来说,它同样具有参考价值,因为Objective-C是iPhone和iPad应用开发的主要语言。 在Objective-C编程中,`NSStep`可能指的是`NSObject`的...

    Objective-C_2.0程序设计

    综上所述,《Objective-C_2.0程序设计》不仅是一本深入介绍Objective-C语言的书籍,也是学习Objective-C编程、Foundation框架、Cocoa和iPhone应用开发的重要资源。无论对于初学者还是有经验的程序员,这本书都提供了...

Global site tag (gtag.js) - Google Analytics