?一些基礎的知識,經常混淆,特整理下
空指針:
1. 沒有存儲任何內存地址的指針就稱為空指針(NULL指針)。
2.被賦值為nil的指針,在沒有被具體初始化之前,為nil。
注意:?
nil和Null區別不是初始化前后的區別,是nil代表對象類型的空指針,Null代表基本數據類型的空指針。
3.nil、Nil、NULL、NSNULL的含義和區別
nil:OC中的對象的空指針
Nil:OC中類的空指針
NULL:C類型的空指針
NSNull:數值類的空對象
此處說一下NSNull,在集合中不能nil值,因為NSArray和NSDictionary中nil有特殊的含義。但是有些時候,需要在集合中存放空值,比如個人信息中,只知道姓名,不知道電話號碼,此時,有必要將電話號碼設置為空,這時,就用到了NSNull。
NSNull中只有一個null方法 :[NSNull null]
[dic setObject:[NSNull null] forKey:@"phoneNumber"];
if(phoneNumber == [NSNull null]){
//...
}
野指針:
1."野指針"不是nil指針,是指向"垃圾"內存(不可用內存)的指針。野指針是非常危險的。
示例:
Student *stu = [[Student alloc] init];
[stu setAge:10];
[stu release];這里已經釋放內存
[stu setAge:10];---》報錯
如果改動一下代碼,就不會報錯
Student *stu = [[Student alloc] init];
[stu setAge:10];
[stu release];
stu = nil;?
[stu setAge:10]; //消息是無法發送出去的,不會造成任何的影響,當然也不會報錯。
補充說明:
1.Student對象接收到release消息后,會馬上被銷毀,所占用的內存會被回收。” 這里執行release只是標記對象占用的那塊內存可以被釋放,但是具體的釋放的時間是不可控的,如果在release之后執行[stu setAge:10];不一定會野指針crash,如果對象內存已經被其他對象覆寫占用,那么會crash,如果沒有沒覆寫,調用依然可以正確執行。
2.向空指針發送消息不會報錯,但是給野指針發送消息會報錯
僵尸對象
遇到exc_bad_access這類問題一般都是僵尸對象引起的,可以開啟僵尸模式定位,我們并沒有保留他,只是在程序運行到該對象的時候會產生問題,沒有誰會運用他,只會定位他然后解決掉
內存回收的本質.
1.申請一塊空間,實際上是向系統申請一塊別人不再使用的空間.
2.釋放一塊空間,指的是占用的空間不再使用,這個時候系統可以分配給別人去使用.
3.在這個個空間分配給別人之前 數據還是存在的.
? ? 3.1.OC對象釋放以后,表示OC對象占用的空間可以分配給別人.
? ? 3.2.但是再分配給別人之前 這個空間仍然存在 對象的數據仍然存在.
4.僵尸對象: 一個已經被釋放的對象 就叫做僵尸對象.
使用野指針訪問僵尸對象.有的時候會出問題,有的時候不會出問題.
1.當野指針指向的僵尸對象所占用的空間還沒有分配給別人的時候,這個時候其實是可以訪問的.
因為對象的數據還在.
2.當野指針指向的對象所占用的空間分配給了別人的時候 這個時候訪問就會出問題.
3.所以,你不要通過一個野指針去訪問一個僵尸對象.
? ? ? ?3.1.雖然可以通過野指針去訪問已經被釋放的對象,但是我們不允許這么做.
僵尸對象檢測.
1.默認情況下. Xcode不會去檢測指針指向的對象是否為一個僵尸對象. 能訪問就訪問 不能訪問就報錯.
2.可以開啟Xcode的僵尸對象檢測.
? ? ? ?2.1.那么就會在通過指針訪問對象的時候,檢測這個對象是否為一個僵尸對象 如果是僵尸對象 就會報錯.
為什么不默認開啟僵尸對象檢測呢?
1.因為一旦開啟,每次通過指針訪問對象的時候.都會去檢查指針指向的對象是否為僵尸對象.那么這樣的話 就影響效率了.
如何避免僵尸對象報錯.
1.當一個指針變為野指針以后. 就把這個指針的值設置為nil
僵尸對象無法復活.
1.當一個對象的引用計數器變為0以后 這個對象就被釋放了.
2.就無法取操作這個僵尸對象了. 所有對這個對象的操作都是無效的.
3.因為一旦對象被回收 對象就是1個僵尸對象 而訪問1個僵尸對象 是沒有意義.