苹果开发教程 Cocoa内存管理笔记

移动开发 iOS
本文介绍的是苹果开发教程 Cocoa内存管理笔记,很详细的介绍了对内存的管理,如何管理,我们来看内容。

苹果开发教程 Cocoa内存管理笔记是本文要介绍的内容,内容分为两种方式进行介绍,我们来看详细内容。

下面的这种方式是不对的

  1. Instance you don’t own is sent release- (void)reset {NSNumber *zero = [NSNumber numberWithInteger:0]; 

创建的是一个autorelease的对象[self setCount:zero];[zero release];//这里释放是危险的}

  1. When you add an object to a collection such as an array, dictionary, or set, the collection takes ownership of 

it.在集合中增加object,那么这个object的所有者就变成了集合了

代码

  1. // ...for (i = 0; i < 10; i++) {NSNumber *convenienceNumber = [NSNumber numberWithInteger:i];  
  2. [array addObject:convenienceNumber];  
  3. }  
  4. //这种情况不需要releaseNSMutableArray *array;NSUInteger i;  
  5. // ...for (i = 0; i < 10; i++) {NSNumber *allocedNumber = [[NSNumber alloc] initWithInteger: i]  
  6. ;[array addObject:allocedNumber];[allocedNumber release];}  
  7. //这种情况需要,此处只是将retain的计数减1而已 

安全返回对象

下面两种方式是正确的

  1. (NSString *)fullName {    
  2.  NSString *string = [NSString stringWithFormat:@"%@ %@", firstName, lastName];    
  3.  return string;    
  4.  }    
  5.      
  6.  (NSString *)fullName {    
  7.  NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName,    
  8.  lastName] autorelease];    
  9.  return string;    
  10.  }  

相反,下面的方式是错误的

  1.  (NSString *)fullName {    
  2.  NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName,    
  3.  lastName] release];    
  4.  return string;    
  5. }   

8 同样,下面的方式也是错的

  1. (NSString *)fullName {    
  2. NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName,    
  3. lastName];    
  4. return string;    
  5. }   

对象拷贝机制

有两种实现拷贝协议的copyWithZone:方法的方式:

使用alloc and init..

使用 NSCopyObject. 

看下面对象的定义

  1. @interface Product : NSObject <NSCopying> 
  2. {  
  3. NSString *productName;  
  4. float price;  
  5. id delegate;  
  6. }  
  7. @end 

拷贝后的内存位置图如下:

假设从supercalass继承了NSCopying,但是父类没有实现NSCopying,那么你要实现的话必须拷贝super的实例,同样包括自己声明的变量。一般情况下安全的方式是使用如alloc,
init..., and set methods

另外一方面,如果super类已经实现了NSCopying,并且在你的类中你声明了一些实例变量,那么你必须实现copyWithZone:

如果类没有继承NSCopying的行为,那么实现copyWithZone: using alloc,init..., and set methods.下面是一个例子

  1. - (id)copyWithZone:(NSZone *)zone  
  2. {  
  3. Product *copy = [[[self class] allocWithZone: zone]  
  4. initWithProductName:[self productName]  
  5. price:[self price]];  
  6. [copy setDelegate:[self delegate]];  
  7. return copy;  

有些继承了NSCopying behavior的类,但是他们的super类的实现可能使用了 NSCopyObject function. NSCopyObject creates an exact shallow copy of an object

by copying instance variable values but not the data they point to. 举个例子, NSCell类采用如下的方式实现copyWithZone

  1. - (id)copyWithZone:(NSZone *)zone  
  2. {  
  3. NSCell *cellCopy = NSCopyObject(self, 0, zone);  
  4. /* Assume that other initialization takes place here. */  
  5. cellCopy->image = nil;  
  6. [cellCopy setImage:[self image]];  
  7. return cellCopy;  

在上面的实现采用的是浅拷贝

对可变长度的对象的拷贝实现 ,要继承NSMutableCopying

Core Foundation Objects in Cocoa中的内存管理

  1. Core Foundation's memory allocation policy is that you need to release values returned   
  2. by functions with “Copy” or “Create” in their name; you should not release values   
  3. returned by functions that do not have “Copy” or “Create” in their name. 

举几个例子

  1. NSString *str = [[NSString alloc] initWithCharacters: ...]; ... [str release];  
  2. is equivalent to  
  3. CFStringRef str = CFStringCreateWithCharacters(...); ...  
  4. CFRelease(str);  
  5. and  
  6. NSString *str = (NSString *)CFStringCreateWithCharacters(...); ...  
  7. [str release];  
  8. and  
  9. NSString *str = (NSString *)CFStringCreateWithCharacters(...);  
  10. ... [str autorelease];  
  11. Memory Management of Nib Objects 

The File’s Owner of a nib file缺省要去释放NIB资源及顶层的对象

NIB文件的全局拥有者是全局应用对象NSApp,但是当Cocoa应用终止时,nib中的顶层对象也没有自动获得dealloc消息,因为NSApp已经被析构了。换句话说,即使nib主文件中,你也不得不管理顶层对象的内存

实际上也不用担心,mac已经有两个特征可以帮助你了

NSWindow对象有一个isReleasedWhenClosed属性,设置为YES则关闭窗口对象时自动关闭相关对象

nib文件的拥有者是一个NSWindowController对象,那么他会调用NSDocument来管理一个NSWindowController的实例,会自动释放他管理的窗口的

所以现实情况就是虽然你要负责释放一个nib文件中的top-level对象,但是只要你的nib文件的owner是一个NSWindowController的实例,那么它会帮你释放的。如果你的一个对象加载了nib自身并且文件的拥有者并不是NSWindowController,那么你可以为nib中的对象定义outlets,这样你就可以在恰当的时候释放他们。如果你不想为每个对象都声明outlet,你也可以这样:

NSNib类的instantiateNibWithOwner:topLevelObjects: 方法来获得nib文件中的所有顶层对象

内存管理总之可以归结为:

(1)你通过带alloc,new,copy的函数创建的对象,你拥有他

(2)通过retain你可以获得拥有权

(3)任何一个对象都可能有很多个owner

(4)你拥有的对象你必须通过发送release或者是autorelease释放他们

(5)你不能释放不是你拥有的对象

(6)对set类型的赋值函数,你可以retain传入的对象,你也可以copy一份,看你自己的要求咯

(7)在函数(void)dealloc中一定要释放你声明的instance变量呀

(8)指针变量使用完了一定要设为nil

(9)你要确定一个对象不被释放掉,你***提前retain一下

(10)在任何时候都不要直接调用dealloc

小结:苹果开发教程 Cocoa内存管理笔记的内容介绍完了,希望本文对你有所帮助!

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

2011-06-17 15:57:46

CocoaXcode苹果

2011-07-28 11:12:25

Cocoa 内存

2011-08-15 16:28:06

Cocoa内存管理

2011-06-17 16:23:49

Cocoa苹果

2011-07-07 09:54:01

Cocoa Core Foundation

2011-08-10 18:37:32

CocoaMac OS X

2011-06-15 17:02:02

CocoaiOS

2011-05-11 17:48:31

CocoaiOS

2011-07-26 15:29:36

Cocoa 模式

2011-07-25 13:15:34

Cocoa MVC 架构

2011-06-17 15:38:15

Cocoa苹果

2011-07-26 10:42:00

Cocoa Cocoa2d 游戏

2011-06-15 16:11:51

UIKitCocoa TouchiOS

2011-07-25 14:32:40

Cocoa 框架 函数

2011-08-11 15:46:55

CocoaCocoa Touch框架

2011-07-21 14:42:45

iOS UIViewCont 内存

2014-07-31 10:48:09

Android内存管理OOM

2011-08-15 16:09:44

Cocoa对象Objective-C

2011-08-15 15:26:20

iPhone开发CocoaXML

2011-08-10 16:27:07

Cocoa TouchPlist
点赞
收藏

51CTO技术栈公众号