iOS 關於僵屍對象和僵屍指針的那些事兒


引言

提到僵屍就感到一種恐怖,大家都知道“僵屍”是沒有生命的,但是它確實是一種存在的類似生命體的一種生物。哈哈,當然本文的重點不是討論“僵屍”,而是有關於ios當中經常遇到的僵屍指針(Zombie Pointer)和僵屍對象(Zombie Object)。

野指針

先來介紹一下野指針,C/C++中對野指針的定義為:野指針就是指向垃圾內存的指針,這個指針地址不是NULL。如果給一個指針賦值為NULL,那么該指針就是一個空指針,可以用if語句判讀。但是對於野指針不能用if語句判斷。

野指針產生的原因

1)指針變量沒有被初始化。任何指針在創建時都不會自動賦值為NULL,那么如果不初始化,它指向的內存地址是不確定的。所以在創建時,應該進行初始化。

char *ptr = NULL;
char *str = (char*)malloc(32);

2)指針被釋放(free或malloc)之后,沒有設置為NULL,誤以為是個合法指針。

void function( void )  
{  
    char* str = new char[100];  
    delete[] str;  
    // Do something  
    strcpy( str, "Dangerous!!" );  
} 

3)指針操作超出了變量的作用范圍。

class A 
{    
    public:
        void Func(void){ cout << “Func of class A” << endl; }
};
void Test(void)
{
    A *p;
    {
        A a;
        p = &a;    // 注意 a 的生命期
    }
    p->Func();        // p是“野指針”
}

函數 Test 在執行語句 p->Func() 時 ,對象 a 已經消失,而 p 是指向 a 的,所以 p 就成了 “野指針”。

僵屍指針

“僵屍指針”就是野指針的一種情況,即該指針指向的對象已經被釋放,但是卻沒有對當前指針賦值為nil。

僵屍對象

簡單的來說,僵屍對象是已經被釋放的對象。如果在程序中再度使用該對象,一般會出現如下報錯:

unrecognized selector sent to instance

今天就遇到了這樣的一個報錯:

解決方案

可以在Xcode的scheme頁面中設置NSZombieEnabled環境變量。點擊Product——>Edit Scheme打開該頁面,然后勾選Enable Zombie Objects 復選框。如下圖所示:

NSZombieEnabled變量用來調試與內存有關的問題,跟蹤對象的釋放過程。啟用了NSZombieEnabled,它會用一個僵屍來替換默認的dealloc實現,也就是在引用計數降到0時,該僵屍實現會將該對象轉換成僵屍對象。僵屍對象的作用是在你向它發送消息時,它會顯示一段日志並自動跳入調試器。啟用NSZombie而不是讓應用直接崩潰掉時,一個錯誤的內存訪問就會變成一條無法識別的消息發送給僵屍對象。僵屍對象會顯示接受到得信息,然后跳入調試器,這樣你就可以查看到底是哪里出了問題。

為什么不默認開啟僵屍對象檢測呢?

因為一旦開啟,每次通過指針訪問對象的時候,都會去檢查指針指向的對象是否為僵屍對象。所以會影響程序的執行效率,建議關閉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM