蘋果開發(fā)教程 Cocoa內(nèi)存管理筆記
蘋果開發(fā)教程 Cocoa內(nèi)存管理筆記是本文要介紹的內(nèi)容,內(nèi)容分為兩種方式進(jìn)行介紹,我們來看詳細(xì)內(nèi)容。
下面的這種方式是不對(duì)的
- Instance you don’t own is sent release- (void)reset {NSNumber *zero = [NSNumber numberWithInteger:0];
 
創(chuàng)建的是一個(gè)autorelease的對(duì)象[self setCount:zero];[zero release];//這里釋放是危險(xiǎn)的}
- When you add an object to a collection such as an array, dictionary, or set, the collection takes ownership of
 
it.在集合中增加object,那么這個(gè)object的所有者就變成了集合了
代碼
- // ...for (i = 0; i < 10; i++) {NSNumber *convenienceNumber = [NSNumber numberWithInteger:i];
 - [array addObject:convenienceNumber];
 - }
 - //這種情況不需要releaseNSMutableArray *array;NSUInteger i;
 - // ...for (i = 0; i < 10; i++) {NSNumber *allocedNumber = [[NSNumber alloc] initWithInteger: i]
 - ;[array addObject:allocedNumber];[allocedNumber release];}
 - //這種情況需要,此處只是將retain的計(jì)數(shù)減1而已
 
安全返回對(duì)象
下面兩種方式是正確的
- (NSString *)fullName {
 - NSString *string = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
 - return string;
 - }
 - (NSString *)fullName {
 - NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName,
 - lastName] autorelease];
 - return string;
 - }
 
相反,下面的方式是錯(cuò)誤的
- (NSString *)fullName {
 - NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@", firstName,
 - lastName] release];
 - return string;
 - }
 
8 同樣,下面的方式也是錯(cuò)的
- (NSString *)fullName {
 - NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName,
 - lastName];
 - return string;
 - }
 
對(duì)象拷貝機(jī)制
有兩種實(shí)現(xiàn)拷貝協(xié)議的copyWithZone:方法的方式:
使用alloc and init..
使用 NSCopyObject.
看下面對(duì)象的定義
- @interface Product : NSObject <NSCopying>
 - {
 - NSString *productName;
 - float price;
 - id delegate;
 - }
 - @end
 
拷貝后的內(nèi)存位置圖如下:
假設(shè)從supercalass繼承了NSCopying,但是父類沒有實(shí)現(xiàn)NSCopying,那么你要實(shí)現(xiàn)的話必須拷貝super的實(shí)例,同樣包括自己聲明的變量。一般情況下安全的方式是使用如alloc, 
init..., and set methods
另外一方面,如果super類已經(jīng)實(shí)現(xiàn)了NSCopying,并且在你的類中你聲明了一些實(shí)例變量,那么你必須實(shí)現(xiàn)copyWithZone:
如果類沒有繼承NSCopying的行為,那么實(shí)現(xiàn)copyWithZone: using alloc,init..., and set methods.下面是一個(gè)例子
- - (id)copyWithZone:(NSZone *)zone
 - {
 - Product *copy = [[[self class] allocWithZone: zone]
 - initWithProductName:[self productName]
 - price:[self price]];
 - [copy setDelegate:[self delegate]];
 - return copy;
 - }
 
有些繼承了NSCopying behavior的類,但是他們的super類的實(shí)現(xiàn)可能使用了 NSCopyObject function. NSCopyObject creates an exact shallow copy of an object
by copying instance variable values but not the data they point to. 舉個(gè)例子, NSCell類采用如下的方式實(shí)現(xiàn)copyWithZone
- - (id)copyWithZone:(NSZone *)zone
 - {
 - NSCell *cellCopy = NSCopyObject(self, 0, zone);
 - /* Assume that other initialization takes place here. */
 - cellCopy->image = nil;
 - [cellCopy setImage:[self image]];
 - return cellCopy;
 - }
 
在上面的實(shí)現(xiàn)采用的是淺拷貝
對(duì)可變長度的對(duì)象的拷貝實(shí)現(xiàn) ,要繼承NSMutableCopying
Core Foundation Objects in Cocoa中的內(nèi)存管理
- Core Foundation's memory allocation policy is that you need to release values returned
 - by functions with “Copy” or “Create” in their name; you should not release values
 - returned by functions that do not have “Copy” or “Create” in their name.
 
舉幾個(gè)例子
- NSString *str = [[NSString alloc] initWithCharacters: ...]; ... [str release];
 - is equivalent to
 - CFStringRef str = CFStringCreateWithCharacters(...); ...
 - CFRelease(str);
 - and
 - NSString *str = (NSString *)CFStringCreateWithCharacters(...); ...
 - [str release];
 - and
 - NSString *str = (NSString *)CFStringCreateWithCharacters(...);
 - ... [str autorelease];
 - Memory Management of Nib Objects
 
The File’s Owner of a nib file缺省要去釋放NIB資源及頂層的對(duì)象
NIB文件的全局擁有者是全局應(yīng)用對(duì)象NSApp,但是當(dāng)Cocoa應(yīng)用終止時(shí),nib中的頂層對(duì)象也沒有自動(dòng)獲得dealloc消息,因?yàn)镹SApp已經(jīng)被析構(gòu)了。換句話說,即使nib主文件中,你也不得不管理頂層對(duì)象的內(nèi)存
實(shí)際上也不用擔(dān)心,mac已經(jīng)有兩個(gè)特征可以幫助你了
NSWindow對(duì)象有一個(gè)isReleasedWhenClosed屬性,設(shè)置為YES則關(guān)閉窗口對(duì)象時(shí)自動(dòng)關(guān)閉相關(guān)對(duì)象
nib文件的擁有者是一個(gè)NSWindowController對(duì)象,那么他會(huì)調(diào)用NSDocument來管理一個(gè)NSWindowController的實(shí)例,會(huì)自動(dòng)釋放他管理的窗口的
所以現(xiàn)實(shí)情況就是雖然你要負(fù)責(zé)釋放一個(gè)nib文件中的top-level對(duì)象,但是只要你的nib文件的owner是一個(gè)NSWindowController的實(shí)例,那么它會(huì)幫你釋放的。如果你的一個(gè)對(duì)象加載了nib自身并且文件的擁有者并不是NSWindowController,那么你可以為nib中的對(duì)象定義outlets,這樣你就可以在恰當(dāng)?shù)臅r(shí)候釋放他們。如果你不想為每個(gè)對(duì)象都聲明outlet,你也可以這樣:
NSNib類的instantiateNibWithOwner:topLevelObjects: 方法來獲得nib文件中的所有頂層對(duì)象
內(nèi)存管理總之可以歸結(jié)為:
(1)你通過帶alloc,new,copy的函數(shù)創(chuàng)建的對(duì)象,你擁有他
(2)通過retain你可以獲得擁有權(quán)
(3)任何一個(gè)對(duì)象都可能有很多個(gè)owner
(4)你擁有的對(duì)象你必須通過發(fā)送release或者是autorelease釋放他們
(5)你不能釋放不是你擁有的對(duì)象
(6)對(duì)set類型的賦值函數(shù),你可以retain傳入的對(duì)象,你也可以copy一份,看你自己的要求咯
(7)在函數(shù)(void)dealloc中一定要釋放你聲明的instance變量呀
(8)指針變量使用完了一定要設(shè)為nil
(9)你要確定一個(gè)對(duì)象不被釋放掉,你***提前retain一下
(10)在任何時(shí)候都不要直接調(diào)用dealloc
小結(jié):蘋果開發(fā)教程 Cocoa內(nèi)存管理筆記的內(nèi)容介紹完了,希望本文對(duì)你有所幫助!















 
 
 
 
 
 
 