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