標籤:objective 記憶體管理 引用計數 oc objetive-c
規則:
- 當你使用 new 、 alloc 或 copy 方法建立一個對象時,改對象的保留計數器的值為 1。當不再使用該對象時,你應該向該對象發送一條 release 或 autorelease 訊息。這樣,該對象將在其使用壽命結束時被銷毀。
- 當你通過其他方法獲得一個對象時,假設該對象的保留計數器的值為 1 ,而且已經被設定為自動釋放,難麼你不需要執行任何操作來確保該對象得到清理。如果你打算在一段時間內擁有該對象,則需要保留它並確保在操作完成時釋放它。
- 如果你保留了某個對象,就需要(最終)釋放或自動釋放該對象。必須保持 retain 方法和 release 方法的使用次數相等。
自動釋放池以棧的形式實現:當你建立了一個新的自動釋放池時,它就被添加到棧頂。接收 autorelease 訊息的對象將被放入最頂的自動釋放池中。如果將一個對象放入一個自動釋放池中,然後建立一個新的自動釋放池,再銷毀該建立的自動釋放池,則這個自動釋放池對象扔將存在,因為容納該對象的自動釋放池仍然存在。
注意:
棧記憶體配置原則:從高到底分配,從低到高存取。
上代碼:
工程檔案—下載連結
main.m 檔案:
//// main.m//// Created by on 15/4/13.// Copyright (c) 2015年 . All rights reserved.//#import <Foundation/Foundation.h>#import "Person.h"#import "Dog.h"int main(int argc, const char * argv[]) { @autoreleasepool {// Person *aPerson = [[Person alloc] init] ;// NSLog( @"引用計數:%ld", aPerson.retainCount ) ;// // [aPerson release] ; // 立即調用 dealloc// //// [aPerson autorelease] ; // 到‘}’時才 調用 dealloc // // NSLog( @"引用計數:%ld", aPerson.retainCount ) ;//引用計數列印不出來0// Person *aPerson = [[Person alloc] init] ; // 1 Dog *aDog = [[Dog alloc] init] ; // 1 aPerson.pet = aDog ; // 2 //在執行 copy 方法時,方法內部就是在執行 NSCopying 協議中的方法,copyWithZone : Dog *newDog = [aDog copy] ; NSLog( @"%@", newDog ) ; [aDog release] ; // 1 [aPerson release] ; // 0// 注意:/* 1、引用計數的增加和減少相等,當引用計數降為0之後,不應該再使用這塊記憶體空間; 2、凡是使用了alloc、retain或者copy、new、mutableCopy讓記憶體的引用計數增加了,就需要使用release或者autorelease讓記憶體的引用計數減少。在一段代碼內,增加和減少的次數要相等; 3、如果擁有一個對象的所有權,那麼需要在該對象不再被使用時釋放其所有權。如果一個對象不歸我們擁有就不要對其做釋放所有權的操作。 */ } return 0;}
Person.h 檔案:
//// Person.h//// Created by on 15/4/13.// Copyright (c) 2015年 . All rights reserved.//#import <Foundation/Foundation.h>#import "Dog.h"@interface Person : NSObject@property (nonatomic, retain) NSString *name ;@property (nonatomic, assign) NSInteger age ;@property (nonatomic, retain) NSString *gender ;@property (nonatomic, copy) Dog *pet ;@end
Person.m 檔案:
//// Person.m//// Created by on 15/4/13.// Copyright (c) 2015年 . All rights reserved.//#import "Person.h"@implementation Person- (void)dealloc { NSLog( @"%s", __FUNCTION__ ) ;// NSLog( @"%@被銷毀啦", self ) ; [_pet release] ; [super dealloc] ;}@end
Dog.h 檔案:
//// Dog.h//// Created by on 15/4/13.// Copyright (c) 2015年 . All rights reserved.//#import <Foundation/Foundation.h>//如果一個類的對象想要被拷貝,需要遵守NSCopying協議並實現協議的相關方法@interface Dog : NSObject<NSCopying>@property (nonatomic, retain) NSString *name ;@end // Dog : NSObject
Dog.m 檔案:
//// Dog.m//// Created by on 15/4/13.// Copyright (c) 2015年 . All rights reserved.//#import "Dog.h"@implementation Dog- (void)dealloc { NSLog( @"%s", __FUNCTION__ ) ; [super dealloc] ;}#pragma mark - NSCopying -- (id)copyWithZone:(NSZone *)zone { // 根據記憶體資訊 zone 棄置站台對象 Dog *dogCopy = [[Dog allocWithZone:zone] init] ; dogCopy.name = self.name ; NSLog( @"副本對象的地址:%p", dogCopy ) ; return dogCopy ;}@end
Objective-C----記憶體管理