Objective-C記憶體管理詳解

來源:互聯網
上載者:User


手動管理記憶體

retain計數是一個相當簡單的概念,Objective-C中的內一個對象都有一個retain計數。retain計數是一個整數。使用alloc函數建立一個對象時,該對象的retain計數設為1.當計數變為0的時候,對象被釋放。一般通過發送retain訊息給對象,從而增加對象的retain計數。發送release給對象,則減少retain計數的值。
手動管理記憶體前,先進入項目的“Build Settings” 裡面,找到“Objective-C Automatic Reference Counting” 設定為 “No”
例如我們要對一個Person類進行手動的記憶體管理:

介面檔案


//Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
    NSString *_name;
}
-(void)setName:(NSString *)name;
-(NSString *)name;
@end

實現檔案:


//Person.m
#import "Person.h"
@implementation Person
-(void)setName:(NSString *)name
{
    _name = name;
}
-(NSString *)name
{
    return _name;
}
-(void)dealloc
{
    NSLog(@"記憶體清理.");
    [super dealloc];
}
@end

主檔案:


//main.m
#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *person = [[Person alloc] init];
        [person setName:@"Mr.柿子"];
        NSString *getName = [person name];
        //計數器-1
        [person release];
        [getName release];
        NSLog(@"The name is %@",getName);
    }

    return 0;
}

Accessor 方法

當變數是常規的int類型方法時,可以建立簡單的accessor方法


//Get Method
-(int) food
{
    return food;  
}
//Set Method
-(void)setFood:(int)x
{
    food = x;
}

但是當變數是一個指標類型的時候,就需要使用常規的3用法了。
第一個用法:retain,然後再釋放
Objective-C
-(void)setFood:(NSDate *)x
{
    [x retain];
    [food release];
    food = x;
}

注意:如果這兩個對象指向同一對象,那麼進行retain和釋放就是多餘的。
第二個用法:改變前先檢查


-(void)setFood:(NSDate *)x
{
    if(food != x){
        [food release];
        food = [x retain];
    }
}

缺陷:必須執行一次額外的if語句。

第三個用法:自動釋放舊的對象
Objective-C
-(void)setFood:(NSDate *)x
{
    [food autorelease];
    food = [x retain];
}

注意:如果存在retain計數錯誤的情況,就必須等迴圈結束後才能發現,這樣不利於跟蹤。前兩個方法在程式崩潰的時候就很容易找到原因。
ARC 記憶體管理
儘管手動引用計數很簡單,但是想要程式順利的執行卻很困難。實際上,這樣的方法雖然減少了記憶體泄露,但是卻帶來了程式崩潰,出錯的問題。
使用ARC後,我們將無須再需要去關注對象的retain計數,二將更多的關注點放在這些對象的關係上。
對象之間的關係就是引用,而參考型別有2種,分別是:強引用和弱引用。
強引用
預設情況下的引用都是強引用。
我們只需要像平常來使用,ARC解決dealloc中強引用的釋放問題,我們也可用使用dealloc方法來解決其他的記憶體清理問題。
弱引用
弱引用與舊的手動引用計數指標相似:沒有隱式的retain,指標值只在記憶體中修改。
然而這樣的引用一直是引起程式崩潰的原因。假如指標沒有被retain,這個對象就被分配,那麼將留下一句殭屍指標,以後使用時,就是一個潛在的引起崩潰的原因。
ARC解決這個問題的方法是指標指向的對象被重新分配時,欄位蔣弱引用設為nil,這就是所謂的“Zeroing Weak reference”.

什麼時候使用弱引用?

當遇到了兩個對象相互retain,最終導致永遠都不會被釋放。這個在ARC中叫做強引用迴圈。
怎麼避免呢?
通過有技巧的使用弱引用,可避免這樣的引用迴圈。


@interface Person : NSObject
{
    Person *parent; //錯了~,這導致了強引用迴圈
    NSMutableArray *children;
}
@end

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.