iOS殭屍物件之研究

滴水微瀾發表於2016-12-27

Zombie Objects物件研究

一、Xcode 關閉ARC

project -> Build settings  搜尋 Automatic Reference Counting      設定為NO

 

二、開啟 殭屍物件 選項 

 

三、程式碼驗證

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    Person *person =[[Person alloc]init];
    NSLog(@"person:%@----%@",[self className:person],NSStringFromSelector(_cmd));
    person.name=@"紅葉";
    
    [person release];
    NSLog(@"person:%@",[self className:person]);
    person.name=@"綠葉";
}
- (NSString*)className:(id)obj{

    const char * name=object_getClassName(obj);
    return [NSString stringWithUTF8String:name];
}

a.關閉ARC,關閉殭屍物件選項時

 

 [person release];執行後,person物件會自動執行dealloc方法。因為Scheme中關閉了殭屍物件選項,所以person物件釋放後並不會生成殭屍物件

當再次呼叫person物件時,報錯型別為:錯誤記憶體地址訪問異常

列印結果:

2016-12-27 15:37:56.769 ZomObj[5515:213898] person:Person----viewDidLoad

 

b.關閉ARC,開啟殭屍物件選項時

在[person release];之前

person物件為Person類,正常使用

在[person release];之後

person物件被釋放了,由於scheme開啟了殭屍物件選項,所以person物件在釋放時呼叫的dealloc方法在底層被swizzle了

dealloc方法執行時,程式碼走的並不是清理資源,回收記憶體。而是copy了一個NSZombie物件模版,並修改zimbie物件的isa指標,形成了一個新的殭屍物件類_NSZombie_Person。所以在[person release];執行之後, 列印的person物件型別為_NSZombie_Person

_NSZombie_Person類中只有一個isa指標,裡面沒有其他的屬性和方法,所以不能響應任何事件,所以在向這個殭屍物件傳送訊息時,就會報錯,並列印出來。這非常有利於除錯。

 列印結果:

2016-12-27 15:48:20.006 ZomObj[5624:218915] person:Person----viewDidLoad

2016-12-27 15:48:20.006 ZomObj[5624:218915] person:_NSZombie_Person

2016-12-27 15:48:20.007 ZomObj[5624:218915] *** -[Person setName:]: message sent to deallocated instance 0x6000000161d0

Message from debugger: Terminated due to signal 9

 

相關文章