野指針訪問不可用內(nèi)存地址 該內(nèi)存已被收回 不在屬于該應(yīng)用
空指針 指向null
關(guān)于OC中的nil, NULL詳解
我相信很多同學(xué)對于這四種表示空的方式肯定不會陌生了,網(wǎng)上也有不少介紹四種方式區(qū)別的篱竭,不過我還是想說一些自己的理解力图。
關(guān)于nil
nil的定義是null pointer to object-c object,指的是一個OC對象指針為空掺逼,本質(zhì)就是(id)0吃媒,是OC對象的字面0值
不過這里有必要提一點就是OC中給空指針發(fā)消息不會崩潰的語言特性,原因是OC的函數(shù)調(diào)用都是通過objc_msgSend進行消息發(fā)送來實現(xiàn)的,相對于C和C++來說赘那,對于空指針的操作會引起Crash的問題刑桑,而objc_msgSend會通過判斷self來決定是否發(fā)送消息,如果self為nil募舟,那么selector也會為空祠斧,直接返回,所以不會出現(xiàn)問題拱礁。
這里補充一點琢锋,如果一個對象已經(jīng)被釋放了,那么這個時候再去調(diào)用方法肯定是會Crash的呢灶,因為這個時候這個對象就是一個野指針了吴超,安全的做法是釋放后將對象重新置為nil,使它成為一個空指針鸯乃,大家可以在關(guān)閉ARC后手動release對象驗證一下鲸阻。(2016.05.24補)
NSString *name = @"Allen";
if (name != nil && [name isEqualToString:@"Allen"]) {
NSLog(@"name: %@", name);
} else {
NSLog(@"name is nil");
}
//or
if ([name isEqualToString:@"Allen"]) {
NSLog(@"name: %@", name);
} else {
NSLog(@"name is nil");
}
上面的兩種判斷都是正確的,我們不必擔(dān)心當(dāng)name為nil時調(diào)用isEqualToString會出現(xiàn)Crash飒责,但是我還是想說赘娄,在使用一個對象之前判斷它是否為nil是一個很好的習(xí)慣,個人覺得有兩個原因:
-
降低時間復(fù)雜度(感覺可以這么說吧)宏蛉,如果你增加了nil的判斷,那么不需要對空指針發(fā)送消息了性置,發(fā)消息其實是件費時的操作拾并。
詳情可以看這里 把判斷為空養(yǎng)成習(xí)慣其實是好事,這樣在你切換語言時也不容易出錯鹏浅。
關(guān)于NULL
*NULL的定義是null pointer to primitive type or absence of data嗅义,指的是一般的基礎(chǔ)數(shù)據(jù)類型為空,可以給任意的指針賦值隐砸。本質(zhì)就是(void )0之碗,是C指針的字面0值。
NSInteger *pointerA = NULL;
NSInteger pointerB = 10;
pointerA = &pointerB;
NSLog(@"%ld", *pointerA);
我們要盡量不去將NULL初始化OC對象季希,可能會產(chǎn)生一些異常的錯誤褪那,要使用nil,NULL主要針對基礎(chǔ)數(shù)據(jù)類型式塌。
關(guān)于Nil
Nil的定義是null pointer to object-c class博敬,指的是一個類指針為空。本質(zhì)就是(class)0峰尝,OC類的字面零值偏窝。
Class class = [NSString class];
if (class != Nil) {
NSLog(@"class name: %@", class);
}
關(guān)于NSNull
NSNull好像沒有什么具體的定義(懵),它包含了唯一一個方法+(NSNull)null,[NSNull null]是一個對象祭往,用來表示零值的單獨的對象伦意。*
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
NSString *nameOne = @"Allen";
NSString *nameTwo = [NSNull null]; //not use nil
NSString *nameThree = @"Tom";
[dictionary setObject:nameOne forKey:@"nameOne"];
[dictionary setObject:nameTwo forKey:@"nameTwo"];
[dictionary setObject:nameThree forKey:@"nameThree"];
NSLog(@"names: %@", dictionary);
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:nameOne];
[array addObject:nameTwo];
[array addObject:nameThree];
NSLog(@"names : %@", array);
NSNull主要用在不能使用nil的場景下,比如NSMutableArray是以nil作為數(shù)組結(jié)尾判斷的硼补,所以如果想插入一個空的對象就不能使用nil默赂,NSMutableDictionary也是類似,我們不能使用nil作為一個object括勺,而要使用NSNull
總結(jié)
其實這幾種空類型還是很好理解的缆八,重要的是我們需要在平時的項目中也切實運用起來,不小心初始化的錯誤可能導(dǎo)致一些難以發(fā)現(xiàn)的Bug疾捍。
作者:北辰明
鏈接:http://www.reibang.com/p/2ea9c3f737ea
來源:簡書
簡書著作權(quán)歸作者所有奈辰,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。