Objective C 中的nil,Nil,NULL和NSNull理解,nilnsnull

來源:互聯網
上載者:User

Objective C 中的nil,Nil,NULL和NSNull理解,nilnsnull

 kenyo網友的原創說法是:做IOS開發的估計都對Objective-C的記憶體管理機制很頭疼,一不小心程式就會出記憶體泄露,我也不例外,前幾天被指標的置nil與release給搞慘了,今和大家詳細解說一下有關Objective-C中nil與release的區別與用法。

    首先說一下他們兩的作用,nil就是把一個對象的指標置為空白,只是切斷了指標與記憶體中對象的聯絡,它對記憶體的釋放沒有什麼作用;而release才是真正用於記憶體釋放的,release後系統會將該塊記憶體標記為可用(可重新分配)。所以nil並沒有釋放記憶體,只有release才是真正釋放記憶體。

    二者使用順序,如果沒有release就直接nil,那麼雖然不會出錯(release一個null 指標是合法的),但卻等於自己製造了記憶體流失,因為nil之後release就已經不起作用了,我之前的教訓就是一不小心把nil擱在了release之前,所以leak一直報記憶體泄露。

    相反,如果先release後設定nil,就不會出現這樣的問題,但是有人就會問,release而沒有設定nil,會怎樣?其實程式可能也不會報錯,但是要知道設定nil其實是為了防止指標錯亂,因為一個對象在release之後,給它所分配的記憶體就已經被釋放了,如果釋放之後不把指標置空的話,系統再誤用到到這個指標時,那麼程式就會崩潰(此種情況特別容易出現在延時調用函數中),如果釋放之後把它的指標置為空白,則即便後面的程式用到該指標,也不會崩潰。所以Objective-C釋放記憶體時必須先release然後nil。

  還有一點,在子龍山人的原創文章中有這樣的話:可能有讀者經常看到,在我的教程的dealloc函數裡面有這樣的代碼:self.xxx = nil;看到這裡,現在你們明白這樣寫有什麼用了吧?它等價於[xxx release];  xxx = [nil retain];(---如果你的property(nonatomic,retian)xxx,那麼就會這樣,如果不是,就對號入座吧)。這就是說,在使用了@property運算子後的類變數會產生set和get方法,而set方法的具體寫法是這樣的:

 

-(void) setNames:(NSArray*)names{
NSLog(@"setNames");
if (_name != name) {
[_name release];
_name = [name retain]; }
}
原來的變數和nil比較,不等於就自動釋放了,然後再執行xxx=[nil retain];語句

 

nil
  • nil 是 ObjC 對象的字面空值,對應 id 類型的對象,或者使用 @interface 聲明的 ObjC 對象。
  • 例如:
    NSString *someString = nil;NSURL *someURL = nil;id someObject = nil; if (anotherObject == nil) // do something
  • 定義:
    // objc.h#ifndef nil# if __has_feature(cxx_nullptr)#   define nil nullptr# else#   define nil __DARWIN_NULL# endif#endif // __DARWIN_NULL in _types.h #define __DARWIN_NULL ((void *)0)

 

Nil
  • Nil 是 ObjC 類類型的書面空值,對應 Class 類型對象。
  • 例如:
    Class someClass = Nil;Class anotherClass = [NSString class];
  • 定義聲明和 nil 是差不多的,值相同:
    // objc.h#ifndef Nil# if __has_feature(cxx_nullptr)#   define Nil nullptr# else#   define Nil __DARWIN_NULL# endif#endif
NULL
  • NULL 是任意的 C 指標空值。
  • 例如:
    int *pointerToInt = NULL;char *pointerToChar = NULL;struct TreeNode *rootNode = NULL;
  • 定義:
    // in stddef.h #define NULL ((void*)0)
NSNull
  • NSNull 是一個代表空值的類,是一個 ObjC 對象。實際上它只有一個單例方法:+[NSNull null],一般用於表示集合中值為空白的對象。
  • 例子說明:
    // 因為 nil 被用來用為集合結束的標誌,所以 nil 不能儲存在 Foundation 集合裡。NSArray *array = [NSArray arrayWithObjects:@"one", @"two", nil]; // 錯誤的使用NSMutableDictionary *dict = [NSMutableDictionary dictionary];[dict setObject:nil forKey:@"someKey"]; // 正確的使用NSMutableDictionary *dict = [NSMutableDictionary dictionary];[dict setObject:[NSNull null] forKey:@"someKey"];
  • 定義:
    /*  NSNull.h    Copyright (c) 1994-2012, Apple Inc. All rights reserved.*/ #import <Foundation/NSObject.h> @interface NSNull : NSObject <NSCopying, NSSecureCoding> + (NSNull *)null; @end
NIL 或 NSNil

ObjC 不存在這兩個符號!

小結

雖然 nil, Nil, NULL 的值相同,理解它們之間的書面意義才重要,讓代碼更加明確,增加可讀性。

參考資料
  • Difference between nil,NIL and null – Stack Overflow
  • Topics for Cocoa: Using Null.
object c 中的BOOL值與bool值

typedef signed char BOOL;  

#define YES      (BOOL) 1

#define NO       (BOOL) 0

從上面的定義我們發現布爾變數的值為 YES/NO,或 1/0 。YES 或 1 代表真,NO 或 0 代表假。比如你定義了一個布爾變數並賦了值:

BOOL enabled = NO;
enabled = 0;

判斷BOOL值為YES:

if(enabled == YES){

}

或者YES可以省略

if(enabled){

}

判斷BOOL值為NO:

if(!enabled){

}

或者

if(enabled != YES){

}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.