Objective-C学习笔记Cocoa生命周期

移动开发 iOS
Objective-C学习笔记Cocoa生命周期是本文要介绍的内容,主要是来学习Cocoa中对象的生命周期,每个对象有一个与之相关联的整数,称做它的引用计数器或保留计数器,来看内容。

Objective-C学习笔记Cocoa生命周期是本文要介绍的内容,主要是来学习Cocoa中对象生命周期对象生命周期包括诞生(通过alloc或new方法实现)、生存(接收消息和执行操作)、交友(借助方法的组合和参数)、释放(当它们的生命结束时最终死去)。当对象生命周期结束时,它们的原材料(内存)将被回收以供新的对象使用。

1、引用计数(reference counting):

每个对象有一个与之相关联的整数,称做它的引用计数器或保留计数器。当某段代码需要访问一个对象时,该代码将该对象的保留计数器值加1,表示“我要访问该对象”。当这段代码结束对象访问时,将对象的保留计数器值减1,表示它不再访问该对象。当保留计数器值为0时,表示不再有代码访问该对象了,因此对象将被销毁,其占用的内存被系统回收以便重用。

当使用alloc、new或copy(生成接收对象的一个副本)创建一个对象时,对象的保留计数器值被设置成1.要增加对象的保留计数器值,可以给对象发送一条retain消息,要减少对象的保留计数器值,可以给对象发送一条release消息。

当一个对象因其保留计数器归0而将被销毁时,Objective-C自动向对象发送一条dealloc消息。你可以在自己的对象中重写dealloc方法。可以通过这种方式释放已经分配的全部相关资源。一定不要直接调用dealloc方法。要获得保留计数器的当前值,可以发送retainCount消息。签名如下:

  1. - (id) retain;      
  2. //申请- (void) release;      
  3. //释放- (unsigned) retainCount;          
  4. //当前计数器值  
  5.  
  6. 例如:[[car retain] setTire: tire atIndex:2];  表示要求car对象将其保留计数器值加1并执行setTire操作。Example:  
  7.  
  8. //   
  9.   //  Main.m   
  10.   //  RetainCount1   
  11.   //  内存管理练习1   
  12.   //  
  13.   //  Created by Elf Sundae on 10/23/10.   
  14.   //  Copyright 2010 Elf.Sundae(at)Gmail.com. All rights reserved.   
  15.  //   
  16.    #import <Cocoa/Cocoa.h> 
  17.  @interface RetainTracker : NSObject  
  18.  @end15   
  19.  @implementation RetainTracker  
  20.    - (id) init  
  21.  {  
  22.      if (self = [super init])  
  23.     {  
  24.          NSLog(@"init: Retain count of %d.",[self retainCount]);  
  25.      }  
  26.      return self;25 }  
  27.   - (void) dealloc28 {  
  28.     NSLog(@"dealloc called.Bye Bye.");  
  29.       [super dealloc];31 }  
  30. @end  
  31.   int main (int argc, const char * argv[])   
  32.  {  
  33.     RetainTracker *tracker = [RetainTracker new];  
  34.      [tracker retain];  
  35.      NSLog(@"%d",[tracker retainCount]);  
  36.      [tracker retain];  
  37.      NSLog(@"%d",[tracker retainCount]);  
  38.     [tracker release];  
  39.      NSLog(@"%d",[tracker retainCount]);  
  40.     [tracker release];  
  41.      NSLog(@"%d",[tracker retainCount]);  
  42.     [tracker retain];  
  43.      NSLog(@"%d",[tracker retainCount]);  
  44.    [tracker release];  
  45.     NSLog(@"%d",[tracker retainCount]);  
  46.      [tracker release];  
  47.    return 0;66 } 

输出:

  1. init: Retain count of 1.  
  2. dealloc called.Bye Bye. 

2、对象所有权(object ownership):

如果一个对象具有指向其他对象的实例变量,则称该对象拥有这些对象。这意味着该实体要负责确保对其拥有的对象进行清理。

当多个实体拥有某个特定对象时,对象的所有权关系就更复杂了,这也是保留计数器值可能大于1的原因。在上面的RetainCount1例子中,main()函数拥有RetainTracker类的对象,因此main()要负责清理该类的对象。

回忆一下在OOP基础章节里Car的engine setter方法:

  1. - (void) setEngine: (Engine *) newEngine; 

以及如何在main()函数中调用该方法:

  1. Engine *engine = [Engine new];[car setEngine: engine]; 

现在哪个实体拥有engine对象?是main()函数还是Car类?

下面是编写setEngine的一种更好的方法:

  1. - (void) setEngine: (Engine *) newEngine  
  2. {  
  3.     [newEngine retain];  
  4.    [engine release];  
  5.    engine = newEngine;  
  6. } // setEngine 

在访问方法中,如果先保留新对象,然后再释放旧对象,这不会出问题。

  1. In your accessors, if you retain the new object before you release the old object, you’ll be safe. 

3、自动释放(Autorelease)

自动释放池(autorelease pool),它是一个存放实体的池(集合),这些实体可能是对象,能够被自动释放。

NSObject类提供了一个autorelease方法:

  1. - (id) autorelease; 

该方法预先设定了一条在将来某个时间发送的release消息,其返回值是接收消息的对象。当给一个对象发送autorelease消息时,实际上是将该对象添加到NSAutoreleasePool中。当自动释放池被销毁时,会向该池中的所有对象发送release消息。

  1. - (NSString *) description   
  2. {  
  3.     NSString *description;   
  4.     description = [[NSString alloc]   
  5.        initWithFormat: @"I am %d years old", 4];   
  6.    return ([description autorelease]);7} // description 

自动释放池的销毁时间:

在使用Foundation库工具中,创建和销毁自动释放池的方法非常明确:

  1. NSAutoreleasePool *pool;pool = [[NSAutoreleasePool alloc] init];…[pool release];  

创建一个自动释放池时,该池自动成为活动的池。释放该池时,其保留计数器值归0,然后该池被销毁。在销毁过程中,该池释放其包含的所有对象。

当时用AppKit时,Cocoa定期自动为你创建和销毁自动释放池。通常是在程序处理完当前事件(如鼠标单击或按键)以后执行这些操作。你可以使用任意多的自动释放对象,当不再使用它们时,自动释放池将自动为你清理这些对象

说明:在Xcode自动生成的代码中使用了另一种销毁自动释放池中对象的方式:-drain方法,该方法只是清空自动释放池而不销毁它。-drain方法只适用于Mac OS X 10.4(Tiger)及更高版本。

自动释放池的工作过程:示例:RetainCount2

  1. OBJECTIVE-C CODE   :RetainCount2   
  2.  
  3.  //  
  4. //  Main.m  
  5. //  RetainCount2  
  6. //  内存管理练习2: 使用自动释放池  
  7. //  
  8. //  Created by Elf Sundae on 10/25/10.  
  9. //  Copyright 2010 Elf.Sundae(at)Gmail.com. All rights reserved.  
  10. //  
  11.  
  12. #import <Cocoa/Cocoa.h> 
  13.  
  14. @interface RetainTracker : NSObject  
  15.  
  16. @end  
  17.  
  18. @implementation RetainTracker  
  19.  
  20. - (id) init  
  21. {  
  22.  if (self = [super init])  
  23.  {  
  24.   NSLog(@"init: Retain count of %d.",[self retainCount]);  
  25.  }  
  26.  return self;  
  27. }  
  28.  
  29. - (void) dealloc  
  30. {  
  31.  NSLog(@"dealloc called.Bye Bye.");  
  32.  [super dealloc];  
  33. }  
  34.  
  35. @end  
  36.  
  37. int main (int argc, const char * argv[])   
  38. {  
  39.  // 创建一个自动释放池  
  40.  NSAutoreleasePool *pool;  
  41.  pool = [[NSAutoreleasePool alloc] init];  
  42.    
  43.  // 创建(new)一个RetainTracket对象  
  44.  RetainTracker *tracker = [RetainTracker new]; // count:1  
  45.  NSLog(@"%d",[tracker retainCount]);  
  46.    
  47.  // 处于演示目的,retain一个trancker  
  48.  [tracker retain]; // count:2  
  49.  NSLog(@"%d",[tracker retainCount]);  
  50.    
  51.  // 向对象发送autorelease消息,将该对象添加到自动释放池pool中  
  52.  [tracker autorelease]; // count: still 2  
  53.  NSLog(@"%d",[tracker retainCount]);  
  54.    
  55.  // release该对象以抵消上面的 retain  
  56.  [tracker release]; //count: 1  
  57.  NSLog(@"%d",[tracker retainCount]);  
  58.    
  59.  NSLog(@"releaseing pool");  
  60.  [pool release];  
  61.    
  62.  return 0;  

小结:Objective-C学习笔记Cocoa生命周期的内容介绍完了,希望通过本文的学习能对你有所帮助!

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-08-04 14:58:37

Objective-C Cocoa NSString

2011-05-11 15:19:01

CocoaObjective-C

2011-07-07 14:22:27

Cocoa 对象 生命周期

2011-08-05 14:03:39

Objective-C 对象 模板

2011-07-28 18:11:18

Objective-C Cocoa 编程

2011-08-16 10:23:04

Objective-CNSAutoreleaXcode常用键

2011-07-27 16:36:03

iphone Objective- 静态库

2011-08-04 13:55:10

Cocoa Objective- 文件

2011-07-22 15:42:39

Objective-C UIView 内存

2009-06-11 11:28:35

JSF生命周期

2011-05-11 14:06:49

Objective-C

2013-08-21 14:57:42

objective-c问题

2011-08-04 11:04:14

Objective-C 面向对象 继承

2011-08-04 10:38:17

Objective-C 预处理程序

2011-06-27 15:48:09

Cocoa TouchObjective-C

2010-07-17 16:31:15

cycle lifebada

2011-07-25 10:03:06

Objective-C 委托

2011-07-25 14:27:10

Objective-C 协议 函数

2011-08-04 13:43:30

Objective-C 私有变量

2015-07-08 10:47:57

Using Swift CocoaObjective-C
点赞
收藏

51CTO技术栈公众号