`

理解ARC在Objective-C中的应用

 
阅读更多

 

参考:http://blog.csdn.net/huyuguo/article/details/7631446

 

原文:http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/

 

名词解释:Automatic Reference Counting(ARC):自动引用计数

ARC在很大程度上消除了手动内存管理的负担,同时省去了追查内存泄露和过度释放对象引起的繁琐操作。尽管ARC非常吸引人,但是不会让你完全忽略内存管理。

下面的告示包含了ARC一些关键方面来帮助你快速建立和运行你的项目。

 

  1. Reference Counted Memory: Quick Revision 
  2. How Automatic Reference Counting Works
  3. Enabling ARC in Your Project
  4. New Rules Enforced by ARC
  5. ARC Qualifiers – Declared Properties
  6. ARC Qualifiers – Regular Variables
  7. Migrating Existing Projects to ARC
  8. Including Code that is not ARC Compliant
  9. Should I Use ARC?

    What Has Changed?



 

ARC之前,你必须手动的retain/release/autorelease对象来确保对应的对象存在,当你需要操作这些对象时。如果忘记retain一个对象,或者多次释放同一个对象,会导致应用内存泄露或者应用崩溃。

在Xcode4.3.2中,除了进行输入时语法检查,新的Apple LLVM编译器将手动管理内存的负担转移给编译器,内省你的代码决定何时进行对象释放。苹果文档描述ARC信息如下:

“ARC is a compiler-level feature that simplifies the process of managing object lifetime(memory management) in Cacoa applications."

ARC减少了进行手动管理内存的琐碎的时间,但是你仍然需要拿出一些精力来处理如何管理你的类中对其他对象的引用。

让我们从头开始吧。。。

Reference Counted Memory:Quick Review

iOS中手动管理引用计数内存的工作方式如下:当使用alloc/init(or other similar method)创建一个对象,返回被创建对象的的retainCount为1,意味着你已经拥有了对象的所有权。

[plain] view plaincopy
  1. NSObject *obj = [[NSObject alloc] init];  
  2. // do somoe stuff  
  3. [obj release];  

在分配初始化一个对象与释放一个对象之间,你可以做你想做的操作,安全的对象不会被自动释放,当需要的时候可以被操作。

同样的,把一个对象添加到自动释放池中,当需要的时候,你操作的对象将继续有效 并且在将来的某个时刻不再被需要时,将被释放。

 

[plain] view plaincopy
  1. - (NSObject *) someMethod  
  2. {  
  3.     NSObject *obj = [[[NSObject alloc] init] aurorelease];  
  4.     return obj;// will be deallocated by autorelease pool later  
  5. }  


How Automatic Reference Counting Works

 

大部分iOS新手接触引用计数内存时都会陷入困境。ARC是在预编译阶段为你的代码添加retain/release/autorelease的。

这不是垃圾回收,引用计数内存没有消失,被用自动化的方式化繁为简。ARC听起来好像有点后续考虑的意味,但是细想一下,在Objectie-C中有多少功能在编译之前是通过预处理源文件的方式来实现的,ARC就是非常具有代表的课题。

当你使用ARC方式来编码时,代码格式如下:

 

[plain] view plaincopy
  1. NSObject *obj = [[NSObject alloc] init];  
  2. // do some stuff  

在ARC预编译阶段代码将会自动的转换成如下的格式:

 

 

[plain] view plaincopy
  1. NSObject *obj = [[NSObject alloc] init];  
  2. // do some stuff  
  3. [obj release]; // ** Added by ARC **  


下面的图表(来自苹果文档)好像暗指有效代码与retain/release的逻辑代码一样长。对于有Objective-C编码经验的人是不准确的,但是对于Objective-C的新人保守估计来看是这样的。

 

Enabling ARC in Your Project

New Rule Enfored by ARC

为了能通过ARC的方式进行编译,必须遵守一些规则。

1.alloc/init objects

像之前描述的,按照之前的方式创建对象,就不必再做retain/autorelease/retainCount操作。你不能间接的操作他们的selector:@selector(retain)和@selector(release)的操作将会被禁止。

2.dealloc methods

通常情况将会自动为你创建,你不必直接调用该方法。尽管你可以创建一个定制的dealloc方法来释放资源而不是实例变量。当创建是定制的方法时,不要调用[super dealloc]方法。编译器将会强行来为你做该操作。

3.declared properties

 

[plain] view plaincopy
  1. // ARC Compliant Declaration  
  2. @property(strong) NSObject *obj;  


ARC之前,我们告诉编译器如何进行内存管理,使用assign/retain/copy参数的命令@property来声明公共属性。这些参数将不会在ARC中使用,我们会使用weak/strong参数来告诉编译器如何来操作属性。

 

4.object pointer in c structures

这是一个禁忌。文档建议使用类而不是结构体的方式来实现,这种方式非常有益因为结构体对于ARC是未知的。结构体将会引起额外的迁移麻烦。尽管,ARC基于文件是无效的。参见下面的"including code that is not ARC compliant"

5.casual(邂逅) casting between id and void*

当操作Core Foundation's C库与Foundation Kit's Objective-C库的方法时,在id与void*数据类型之间将会进行频繁的转换。就像我们所知道的 Toll Free Bridging(点击打开链接).

使用ARC你必须提供hints/qualifiers 来告诉编译器当CF对象进入或者退出控制范围来进行内存管理。这些标示符包括__bridge,__bridge_retain and __bridge_transfer.同时,你需要调用CFRetain和CFRelease 来进行内存管理 Core Foundation 对象。

这是一个非常高级的话题,如果你不知道CF Object,现在并不需要担心什么。

6.@autoreleasepool instead NSAutoReleasePool

ARC编译代码不能使用NSAutoReleasePool,必须使用@autoreleasepool{}块.任何一个ARC编译或迁移的工程中的main.m文件是一个非常好的例子。

 

[plain] view plaincopy
  1. int main(int argc,char *argv[])  
  2. {  
  3.     @autoreleasepool{  
  4.         return UIApplicationMain(argc,argv,nil,NSStringFromClass([ExampleAppDelegate class]));  
  5.     }  
  6. }  

7.other gotchas(感叹词)
基于内存的区域已经不存在啦(很明显说的不是在程序运行的时候);你不能使用NSAllocateObject 或NSDeallocateObject.

 


ARC Qualifiers - Declared Properties

作为编程人员,我们通常会决定是否定义一些局部或全局的变量或常量等等。同样,我们必须决定我们的和其他对象相关的属性。我们使用strong/weak标示符来告知编译器这些关系。

Strong References

一个对象的强引用会阻止被引用的对象被释放掉。换句话来讲,创建了一个所属关系。考虑到之前的情况,你将会这样来操作:

[plain] view plaincopy
  1. // Non-ARC Compliant Declaration  
  2. @property(retain) NSObject *obj;  

ARC下通过如下的方式来确保一个类实例拥有一个对象的所有权(ie.不能被释放知道所有者进行释放时)

[plain] view plaincopy
  1. // ARC Compliant Declaration  
  2. @property(strong) NSObject *obj;  


Weak References

 

一个对象的弱引用不能阻止被释放掉。换句话来说,不能创建所有权拥有关系。

[plain] view plaincopy
  1. // Non-ARC Compliant Declaration  
  2. @property(assign) NSObject *parentObj;  

ARC下如下

[plain] view plaincopy
  1. // ARC Compliant Declaration  
  2. @property(weak) NSObject *parentObj;  


 

ARC Qualifiers - Regular Variables

Variables Qualifiers

上面的例子描述了我们如何创建属性并进行管理,我们拥有的普通变量如下:

[plain] view plaincopy
  1. __strong  
  2. __weak  
  3. __unsage_unretained  
  4. __autoreleasing  

通常来讲,这些额外的标示符不会被经常使用。你可能是第一次遇到这些标示符,其他的会在使用迁移工具是遇到。对于一个新的工程,尽管你通常不需要他们,在你定义属性时大部分会使用strong/weak

 

__strong 是默认的类型,不需要打印。这意味着使用alloc/init创建的任何对象在当前有效范围内将保留整个生命周期。

__weak 指对象在任何时刻都能被销毁。__weak变量被销毁时,变量将被置为nil。

__unsafe_unretained很像__weak,但是当对象被释放时,指针不会被置为nil,指针会被随即赋值。

__autoreleasing,not to be confused with calling autorelease on an object before returning it from a method,this is used for passing objects by reference,for example when passing NSError objects by reference such as [myObject performOperationWithErro:@tmp];

Source:LLVM Clang Objective-C Automatic Reference Counting Documentation

NB:We have found @property declarations using 'retain' with ARC enabled(ie.instead of 'strong')do not cause compiler warnings and yield the same compiled result.This could change in future so stick to 'strong' fro clarify.

Migrating Existing Projects to ARC

Xcode 4.3.2提供了一个转换工具将现存代码迁移到ARC,不能自动迁移,需要手动转换。



Including Code that is not ARC Compliant

...

Should I User ARC?

...

ARC Resources:

...

other iOS Resources

http://longweekendmobile.com/2010/07/28/resources-for-learning-iphone-programming/

分享到:
评论

相关推荐

    Objective-c语言学习-快速入门完整版完整版

    Objective-C是一种强大的面向对象编程语言,它是苹果生态系统中开发iOS和macOS应用程序的主要语言。本教程将通过一系列的PPT课件,引导你快速入门Objective-C,这些课件覆盖了从基础到高级的重要概念,是《iPhone与...

    Objective-C编程全解最新版.pdf.zip

    1. **Objective-C基础**:Objective-C是在C语言基础上扩展的,因此,理解C语言的基本语法是必要的。Objective-C添加了消息传递机制、类和协议等面向对象特性。 2. **消息传递**:Objective-C中的对象通过发送消息来...

    Objective-C高级编程 iOS与OS X多线程和内存管理_Objective-C_ios_

    总的来说,《Objective-C高级编程:iOS与OS X多线程和内存管理》是一本深入实践的指南,它将帮助开发者掌握Objective-C在实际开发中的高级技巧,提升应用的性能和稳定性,对于想要深入理解Apple平台开发的程序员来说...

    Objective-C与Objective-C++的混用代码示例

    Objective-C是基于C语言的,主要用于构建iOS和macOS应用程序,而Objective-C++则是Objective-C的一个扩展,它引入了C++的特性,使得开发者可以同时利用Objective-C的动态特性和C++的面向对象编程能力。 ### ...

    在Objective-C中使用C++

    Objective-C是C语言的超集,这意味着任何有效的C代码都可以在Objective-C中使用。由于C++也是C的超集,因此Objective-C也能够直接支持C++代码。开发者可以在Objective-C类中嵌入C++代码,反之亦然。 2. **命名空间...

    Objective-C.2.0 中文版.pdf & Objective-C.chm

    首先,"Programming In Objective-C.chm" 是一本关于Objective-C编程的电子书,可能涵盖了语言的基本语法、类和对象的概念、消息传递机制、内存管理(在Objective-C中是ARC,即自动引用计数)、类别、协议、 Blocks...

    Objective-C2.0程序设计第二版中文版及代码

    《Objective-C 2.0程序设计》和《Effective Objective-C 2.0》两本书将深入讲解以上知识点,并提供实践示例,帮助读者更好地理解和应用Objective-C 2.0。通过学习这些内容,开发者能够熟练地构建高效、稳定、用户...

    Objective-C

    Objective-C是在C语言的基础上扩展了Smalltalk式的面向对象特性,使得它既有C语言的强大功能,又具备了面向对象编程的灵活性。 在Objective-C中,类是所有对象的基础。类定义了一组属性(实例变量)和方法(函数)...

    objective-c编程 第2版=objective-c program 2nd edition_13889311

    然而,随着ARC(Automatic Reference Counting)的引入,现在的Objective-C开发更倾向于自动内存管理,这也会在新版教材中有所体现。 5. **Foundation框架**:Objective-C的开发离不开Foundation框架,它提供了大量...

    objective-c基础教程

    综上所述,《Objective-C基础教程》作为一本介绍Objective-C语言及其在iOS开发中应用的专业书籍,不仅适合初学者入门学习,也对有经验的开发者有着重要的参考价值。通过深入学习本书,读者可以全面掌握Objective-C的...

    Objective-C基础教程(Learn Objective-C)随书源码下载

    在Objective-C中,内存管理主要依赖于ARC(Automatic Reference Counting),它自动跟踪对象的引用计数,当对象不再被引用时自动释放内存。然而,理解引用计数和弱引用的概念对于防止内存泄漏至关重要。 10. **GCD...

    objective-c的计算器

    7. **视图和控制器**:尽管描述中并未提及用户界面,但在实践中,Objective-C计算器通常会涉及UIKit框架,包括UIView和UIViewController。ViewController将处理用户交互,更新模型并展示结果。 8. **事件处理**:...

    Objective-C 编程语言.pdf

    从给定的文件信息来看,这是...尽管Swift的出现和发展对Objective-C构成了一定的挑战,但Objective-C依然在很多项目中发挥着关键作用,对于希望深入理解苹果平台开发的程序员来说,掌握Objective-C仍然是非常有价值的。

    这是一个基于Objective-C语言的基础案例集。旨在用于给初学者快速了解Objective-C语言的语法。.zip

    这个案例集可能包含了这些概念的实际应用,通过学习和实践,初学者能够深入理解Objective-C的核心特性,并逐步提升iOS或macOS开发技能。文件名"ocprjs-master"可能指的是Objective-C编程资源库的主目录,里面可能...

    《Objective-C程序设计(第6版)》

    在Objective-C程序设计的最新版本中,已经针对最新的Xcode开发环境、iOS操作系统以及OS X Mavericks系统进行了重大升级。这种升级不仅包括了Objective-C语言的最新功能和技术,而且也包含了对新版Xcode、iOS和OS X ...

    Learn objective-c on the mac配套实例代码

    - **文件操作**:Objective-C 提供了读写文件的方法,可能在例子中涉及文件的保存和加载。 - **网络编程**:如何使用 NSURLSession 进行网络请求,或者使用 NSInputStream 和 NSOutputStream 处理流数据。 - **动画...

    Objective-C2.0程序设计习题官方答案

    Objective-C2.0是苹果公司开发的一种面向对象...通过学习和实践这些知识点,并参考"Objective-C2.0程序设计习题官方答案"中的解析,你可以加深对Objective-C2.0的理解,提升编程能力,为iOS或Mac应用开发打下坚实基础。

    Objective-C基础教程源代码 Learn objective-C on the Mac Mark Dalrymple著书

    现代Objective-C使用ARC(Automatic Reference Counting),自动管理内存,但仍需理解其工作原理,以避免内存泄漏。 7. ** Blocks 和 Grand Central Dispatch (GCD)**:Objective-C支持Blocks,一种内联函数或闭包...

Global site tag (gtag.js) - Google Analytics