OC 30 day
野指針就是指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的)指針變量在定義時如果未初始化,其值是隨機的,指針變量的值是別的變量的地址,意味著指針指向了一個地址是不確定的變量,此時去解引用就是去訪問了一個不確定的地址,所以結果是不可知的。
定義一個指針變量,沒有初始化,這個指針變量的值是一個垃圾值,指向一個隨機空間,這個指針叫做wild Pointer。
指針指向的對象已經被回收了。這樣的只知叫做wild Pointer。
內存回收的本質:
申請一個變量,實際下就是向系統申請指定字節數空間的。這些空間系統就不會再分配給別人了。
當變量被回收的時候,代表變量佔用的字節空間從此以後系統可以分配給別人使用了。
但是字節空間中儲存的資料還在,
回收對象:
所謂的對象回收,指的是對象佔用的空間可以分配給別人。
當這個對象佔用的空間沒有分配給別人之前,其實對象數據還在。
鑑於以上的知識,請看下面這段程式碼。
int main(int argc, char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc]init];
p1.name = @"猴子";
NSUInteger count = [p1 retainCount];
NSLog(@"count = %lu",count);
[p1 release];
[p1 message];
}
}
這對程式碼會不會crash?
一個已經被釋放的對象,但是這個對象所佔的空間還沒有分配給別人,這樣的對象叫做zombie objects。我們透過wild pointer去訪問zombie objects 的時候。有可能沒問題,也有可能會有問題。當殭屍對象佔用的空間還沒有分配給別人的時候,這是可以的。
當殭屍對象佔用的空間分配給別人使用的時候,就不可以。
就希望如果訪問的是Zombie Objects,無論如何報錯。
Zombie Objects實時檢查機制,可以將這個機制打開。打開之後,只要訪問殭屍對象,無論空間是否分配,就會報錯。
在edit scheme 裡面選取run -> Diagnostics 打開 Zombie Objects
一但打開Zombie Objects檢測,那麼在每訪問一個對象的時候,都會先檢查這個對象是否為一個Zombie Objects對象。這樣是極其消耗性能的。
當一個指針稱為野指針以後,將這個指針的值設為nil。
int main(int argc, char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc]init];
p1.name = @"猴子";
NSUInteger count = [p1 retainCount];
NSLog(@"count = %lu",count);
[p1 release];
p1 = nil;
[p1 message];
}
}
當一個指針的值為nil,通過這個指針去調用對象發法的時候(包括點語法),不會報錯。只是沒有任何反應。但是如果直接訪問屬性,就會報錯。
以下程式碼是無法使用的,因為殭屍是無法復活的,因為他已經火化了。
int main(int argc, char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc]init];
p1.name = @"猴子";
NSUInteger count = [p1 retainCount];
NSLog(@"count = %lu",count);
[p1 release];
[p1 retain];
}
}