`
huobengluantiao8
  • 浏览: 1028215 次
文章分类
社区版块
存档分类
最新评论

Objective-C语法之内存管理

 
阅读更多

1、Objective-C内存管理简介:

Objective-C需要自己考虑内存的管理,对于从Java, C#等语言转向Objective-C平台的程序员新手来说,这是个很大的挑战。幸运的是,如果熟悉了Objective-C的内存管理机制,手工管理内存也没有那么可怕。Objective-C的内存管理介于C/C++和Java C#直接,不像C/C++语言内存管理全部需要程序员一手包办,也不像Java C#语言有那么完备的内存垃圾回收器。(Objective-C 2.0有GC机制,不过不支持IOS)。那他是怎么管理内存的呢?通过引用计数进行管理的。PS:在iOS 5后增加了Automatic Reference Counting(ARC 自动引用计数)特性,这样程序员不需要自己操心管理内存了,ARC和GC不一样,ARC是编译器的行为。ARC后面再讲。不过熟悉Objective-C的内存管理机制是非常必要的。

2、内存管理原理:

Objective-C内存管理模型是基于对象的所有权。如果你拥有这个对象,那么你就有责任去释放它。一个对象可以有多个拥有者。如果这个对象的拥有和为0时,系统将自动释放这个对象。对象的所有权和释放有四个原则:

  • 任何你创建的对象你都获得其所有权。(包括 alloc ,new ,copy等关键字获得的对象)
  • 通过retain获得对象的所有权
  • 如果你不需要一个对象了,你必须释放所有权
  • 你不能释放你没有所有权的对象
引用计数(retainCount)是Objective-C对象引用的唯一依据。调用实例管理的release方法后,此属性减1,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法。

图片来自苹果官网。

3、示例:环境是在不选择ARC的环境下

新建Person类,使他继承与NSObject,在.m文件中实现dealloc方法:
- (void) dealloc  
{  
    NSLog (@"dealloc called. Bye Bye.");  
    [super dealloc];  
    
} 
在引用计数为0时,这个方法就会被调用,证明这个对象被销毁。

创建一个对象,打印它的引用计数
    Person *person = [[Person alloc] init];
    
    NSLog(@"对象person的retainCount: %d", [person retainCount]);

对象personretainCount: 1

我们增加1

   Person *person = [[Person alloc] init];
    NSLog(@"对象person的retainCount: %d",[person retainCount] );
    [person retain];
    NSLog(@"对象person的retainCount: %d", [person retainCount]);

打印结果:

对象personretainCount: 1

对象personretainCount: 2

和传说的一样,retainCount增加了。可以有在release时,减少到1时就不再减 了

    Person *person = [[Person alloc] init];
    NSLog(@"对象person的retainCount: %d",[person retainCount] );
    [person retain];
    NSLog(@"对象person的retainCount: %d", [person retainCount]);
    [person release];
    [person release];
    NSLog(@"对象person的retainCount: %d", [person retainCount]);
这个代码最后打印出来的retainCount是0吗?打印结果:
2012-07-05 16:05:29.830 ObjectiveCTest[2847:f803] 对象person的retainCount: 1
2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] 对象person的retainCount: 2
2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] dealloc called. Bye Bye.
2012-07-05 16:05:29.832 ObjectiveCTest[2847:f803] 对象person的retainCount: 1
震惊了,第一次release 时retainCount减1了,再release , d对象的dealloc called了,但是retainCount 还是1.在stackoverflow.com的查了一下,有人说这个retainCount没什么用。。。。可以事实的确如retainCount是1,对象被干掉了。有人说,要把person = nil。这样retainCount就是0了。试了下,nil的 retainlCount永远是0.这个赋值没有意义。

4、NSAutoreleasePool自动释放内存

如果仅仅是创建,释放,这样对应,就很好理解。但是大多数人不理解的是自动释放内存这个地方,感觉琢磨不透,但其实原理也很简单。
C/C++编程时有个很重要的对内存管理的原则:谁创建谁销毁。但是这个原则在有些情况下却无法遵守:比如让一个普通函数返回一块内存区域。函数调用者必须在函数调用完毕后自己负责销毁这块内存,而在Objective-C的自动内存释放的机制下,就不用那么烦恼了。

先看看最经典的程序入口程序,也用到自动释放。

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
我们先把pool看成一个普通对象,先是alloc,pool的retainCount为1。
第三句release,retainCount为0,自动调用它的dealloc方法。它和任何其它普通对象没 任何区别。
神奇的地方在哪里?
NSAutoreleasePool内部包含一个数组(NSMutableArray),用来保存声明为autorelease的所有对象。如果一个对象声明为autorelease,系统所做的工作就是把这个对象加入到这个数组中去。NSAutoreleasePool自身在销毁的时候,会遍历一遍这个数组,release数组中的每个成员。如果此时数组中成员的retain count为1,那么release之后,retain count为0,

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    Person *person = [[Person alloc] init];
    NSLog(@"对象person的retainCount: %d",[person retainCount] );
    [person autorelease];
    NSLog(@"到这里,person还没被释放");
    [pool release];

打印结果:

2012-07-05 16:34:38.823 ObjectiveCTest[3045:f803] 对象person的retainCount: 1
2012-07-05 16:34:38.823 ObjectiveCTest[3045:f803] 到这里,person还没被释放
2012-07-05 16:34:38.824 ObjectiveCTest[3045:f803] dealloc called. Bye Bye.
在调用pool release的时候,person才被释放。这就是自动释放的神奇的地方,这样就可以创建对象

著作权声明:本文由http://blog.csdn.net/totogo2010/原创,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!



分享到:
评论

相关推荐

    Objective-C程序设计

    《objective-c程序设计》通过大量的实例系统地介绍了objective-c语言的基本概念、语法规则、框架、类库及开发环境。读者在阅读《objective-c程序设计》后,可以掌握objective-c语言的基本内容,并进行实际的iphone/...

    Objective-C的语法与Cocoa框架

    1. GNUStep的安装 2. 类定义 3. Objective-C中的布尔类型 4. Objective-C中的null ...14. 内存管理 15. 常用的类型 16. 写入和读取属性 17. 对象的复制 18. 多线程 19. KVC 与KVO 20. 谓词NSPredicate

    Effective Objective-C 2.0

    从语法、接口与api设计、内存管理、框架等7大方面总结和探讨了objective-c编程中52个鲜为人知和容易被忽视的特性与陷阱。书中包含大量实用范例代码,为编写易于理解、便于维护、易于扩展和高效的objective-c应用提供...

    [Objective-c程序设计].杨正洪等.扫描版

    《Objective-C程序设计》(作者杨正洪、郑齐心、李建国)通过大量的实例系统地介绍了Objective-C语言的基本概念、语法规则、框架、类库及开发环境。读者在阅读本书后,可以掌握Objective-C语言的基本内容,并进行...

    Objective-C Programming The Big Nerd Ra - Hillegass, Aaron

    接着对Objective-C和Foundation做了简单明了的介绍,其中包括Objective-C的语法知识,Foundation的常用类,还有内存管理、常用的设计模式等知识。在读者具备了一定的Objective-C知识后,作者用了两章的篇幅,...

    Objective-C培训资料

    Objective-C Objective-C Objective-C Objective-C 培训教程 主要章节提示: 第 一 章 程序整体语法结构 第 二 章 数据类型 第 三 章 字符串 第 四 章 内存管理 第 五 章 对象的初始化 第 六 章 存取器 第 七 章 ...

    Objective-C培训教程

    第二章 数据类型 第三章 字符串 第四章 内存管理 第五章 对象的初始化 第六章 存取器 第 七 章 继承 第 八 章 动态绑定和id类型 第九章 分类和协议 第十章 属性列表 第十一章 复制对象 第十二章 归档

    Object-C语言教程&案例,要点难点,代码示例,代码解析

    基础语法:熟悉C语言基础是前提,Objective-C是在C语言的基础上增加了面向对象特性。 面向对象:理解类(Class)、对象(Object)、实例变量(Instance Variables)、方法(Methods)、继承(Inheritance)、封装...

    传智博客-Objective-C PPT

    本套PPT,拥有以下OC语言的内容: 一、OC的三大特性(封装、继承、多态) 二、OC的特有语法(点语法、@property、@synthesize关键字、id、构造方法、...三、内存管理 四、协议(protocol)代码块(block) 五、ARC 等等

    PPT03-Objective-C

    面向对象语法 OC特有语法 内存管理 Category Protocol block ARC

    Objective-C 培训教程

    第 一 章 程序整体语法结构 ...第四章 内存管理 第五章 对象的初始化 第六章 存取器 第 七 章 继承 第 八 章 动态绑定和id类型 第九章 分类和协议 第十章 属性列表 第十一章 复制对象 第十二章 归档

    简单讲解Objective-C的基本特性及其内存管理方式

    Oc语言在c语言的基础上,增加了一层最小的面向对象语法,完全兼容C语言,在OC代码中,可以混用c,甚至是c++代码。 可以使用OC开发mac osx平台和ios平台的应用程序。 拓展名:c语言-.c OC语言.-m 兼容C++.-mm 注:...

    使用Objective-C进行iOS移动开发

    此外、面向对象、结构体、类Class,以及手动内存管理、自动内存管理、协议与抽象类型、错误处理、iOS开发中的常见概念、Xcode操作、多媒体编程、网络编程、数据解析和加密、Sqlite数据库、多线程编程、内购等实用...

    object开发的基本流程.doc

    同时,你还需要熟悉Objective-C的语法和特性,如内存管理、协议和代理等。 构建和编译:在编写完代码后,你需要构建和编译你的项目。Xcode提供了构建和编译的功能,它会将你的源代码转换成可执行文件。在编译过程中...

Global site tag (gtag.js) - Google Analytics