Objective-C'de nil ve NULL kullanmalıyım?


170

Bu örnek kod:

NSDictionary *myDictionary = [NSDictionary dictionary];
NSNumber *myNumber = [myDictionary valueForKey: @"MyNumber"];
NSLog(@"myNumber = %@", myNumber); // output myNumber = (null)

if (myNumber == nil)
    NSLog(@"test 1 myNumber == nil");

if (myNumber == NULL)
    NSLog(@"test 2 myNumber == NULL");

if ([myNumber isEqual:[NSNull null]])
    NSLog(@"test 3 myNumber == [NSNull null]");

Ne zaman nil, NULL ve [NSNull null] kullanmalıyım?


4
Amaç C sorusu ile ilgilidir.
Biranchi

nilNULLobjc örneği için bir tür anlamına gelir . Böylece belirli bir değeri objc örneği veya genel işaretçi için tasarlanmıştır işaretleyebilirsiniz. Tip yönetimi ve güvenliği göz önüne alındığında, bu size çok yardımcı olacaktır.
eonil

4
nilve null/ NULLaynıdır - her ikisi de sıfır olarak tanımlanır. Bir formalite olarak, nilObjective-C NULLkodlarken ve normal C / C ++ ifadelerini / çağrılarını kodlarken kullanın . NSNullAncak, tamamen farklı bir şeydir. Örneğin, nil / null işaretleyicilerine izin verilmeyen NSDictionarys içinde "hiçbir şeyi" temsil etmek için yer tutucu görevi gören tek bir nesne.
Hot Licks

İyi açıklama için bağlantıya bakın [burada] [1] [1]: stackoverflow.com/questions/5908936/…
Ameer

Yanıtlar:


114

Kullanabileceğiniz nilher yerde kullanabilirsiniz null. Temel fark, mesaj gönderebilmenizdir nil, böylece nullçalışamayacağınız bazı yerlerde kullanabilirsiniz .

Genel olarak, sadece kullanın nil.


12
teknik olarak, bunlar tamamen eşittir, hem nil hem de NULL'a mesaj gönderebilirsiniz. Deyimsel olarak nil genellikle bir nesneyi temsil etmek için kullanılır
cobbal

41
Ayrıca, MacTypes.h'de var#define nil NULL
cobbal

8
Evet, kobaltın dediği gibi, onlar aynı. NULL'un 0x0'a bir işaretçi olduğu, bağlamsal olmayan bir obj-c nesnesinin ve Nil'in var olmayan bir objektif-c sınıfı olduğu, ancak teknik olarak hepsinin sadece 0 olduğu bağlamsal bir referanstır. null - null, Java veya C # biçimindedir, ancak Objective-C biçiminde değildir.
Jason Coco

16
Kabul edilen bu cevap [NSNull null], bunun çok farklı bir canavar olduğunu kabul etmiyor. NSNull Sınıfı Başvurusu'ndan alıntı yapmak için , "NSNull sınıfı, toplama nesnelerindeki (sıfır değerlerine izin vermeyen) null değerleri temsil etmek için kullanılan tek bir nesne tanımlar." Ayrıca Sayı ve Değer Programlama Konularının NSNull Kullanılması bölümüne bakın .
Rob

"Temel fark, nil'e mesaj gönderebilmenizdir" - mesaj da gönderebilirsiniz NULL.

313

Türlerinde farklılık gösterirler. Hepsi sıfır, ama NULLbir olduğunu void *, nilbir olduğunu idve NilSınıf göstericidir.


14
Farkı duydum en iyi açıklama (: Teşekkürler.
Jacob

3
Bu, daha fazla oyu olduğu için değil, sorulan soruya en iyi açıklamaya sahip olduğu için kabul edilen cevap olmalıdır.
James Mertz

5
NULLV zarif açıklaması nil, ama bu ciddi işareti yeniden özlüyor [NSNull null]. Sayı ve Değer Programlama Konuları ve NSNull Sınıf Referansı'nın NSNull Kullanılması bölümüne bakın .
Rob

Her ikisi de işaretçi gibi görünüyor void *. Burada farklı bir cevap zaten bahsediyor, ama eğer kazarsanız objc.h, hattı bulacaksınız #define nill __DARWIN_NULL.
gkb0986

1
Bu cevap kulağa hoş geliyor ama diğer cevaplara göre yanlış.
n13 26:14

30

nil , bir nesneye (Objective-C'deki id tipi) bağlı / karşılık gelen boş bir değerdir. nil referans / adres yok, sadece boş bir değer.

NSString *str = nil;

Yani bir nesne ile uğraşıyorsak, sıfır kullanılmalıdır.

if(str==nil)
    NSLog("str is empty");

Şimdi NULL , Objective-C'de nesne olmayan işaretçi (C işaretçisi gibi) için kullanılır. Gibi nil , NULL hiçbir değeri ne de adres var.

char *myChar = NULL;
struct MyStruct *dStruct = NULL;

Eğer bir durum varsa, benim yapı (yapı türü değişkeni) boş olup olmadığını kontrol etmek gerektiğinde , ben kullanacağım:

if (dStruct == NULL)
    NSLog("The struct is empty");

Başka bir örnek verelim,

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

Of anahtar değeri gözlemci , bağlam C işaretçi veya bir amacı, bir referans olması gerekir. Burada bağlam için nil kullanamayız ; NULL kullanmalıyız .

Son olarak NSNull sınıfı, toplama nesnelerinde (NSArray, NSDictionary) null değerleri temsil etmek için kullanılan tekli bir nesne tanımlar. [NSNull boş] olacak döner NSNull tekil örneği. Temel olarak [NSNull null] uygun bir nesnedir.

Koleksiyon türü nesnesine nil nesnesi eklemenin bir yolu yoktur. Bir örnek verelim:

NSMutableArray *check = [[NSMutableArray alloc] init];
[check addObject:[NSNull null]];
[check addObject:nil];

İkinci satırda, herhangi bir hata almayacağız, çünkü bir koleksiyon türü nesnesine bir NSNull nesnesi eklemek son derece adil. Üçüncü satırda, "nesne nil olamaz" hatası alırız. Çünkü nil bir nesne değildir.


Dizide nil / null uygulamasından bahsetmek için +1.
Michael

19

NULL ve nil birbirine eşittir, ancak nil bir nesne değeridir, NULL ise genel bir işaretçi değeridir ( (void*)0spesifik olarak). [NSNull null]nil'e izin verilmeyen durumlarda nil için ayakta durmayı amaçlayan bir nesnedir. Örneğin, bir NSArray içinde nil değerine sahip olamazsınız. Yani bir "nil" temsil etmek gerekirse, kullanabilirsiniz [NSNull null].


12

Aşağıdakileri buldum:

objc.h

#define Nil __DARWIN_NULL   /* id of Nil class */
#define nil __DARWIN_NULL   /* id of Nil instance */

_types.h

#define __DARWIN_NULL ((void *)0)

stddef.h

#undef NULL
#ifdef __cplusplus
#undef __null  // VC++ hack.
#define NULL __null
#else
#define NULL ((void*)0)
#endif

MacTypes.h

#ifndef NULL
#define NULL    __DARWIN_NULL
#endif /* ! NULL */
#ifndef nil
    #define nil NULL
#endif /* ! nil */

Göründüğü gibi, kavramsal olandan başka bir fark yoktur.



7

Her ikisi de sadece tipik sıfırlar. İşlevsel olarak, aralarında hiçbir fark yoktur. yani.,

#define NULL ((void*)0)
#define nil ((id)0)

Bir fark var, ancak sadece kodu ve okuyan diğer insanlar için, derleyici umursamıyor.

Nil bir şey daha bir nesne değeri iken NULL genel bir işaretçi değeri.


6

Modern OS X ve iOS SDK'larında:

  • nilve Nilve NULLamaç-C aynıdır ve C ++ 11 önce amaç-C ++ içindedir.
  • nilve Nilve std::nullptrC ++ 11 amaç-C ++ aynıdır.

Stilistik olarak, birçok kişi nilObjective-C nesneleri ve NULLveya nullptrdiğer işaretçi türleri için kullanmayı tercih eder . Şimdi kendim kullanıyorumnil her yerde kullanıyorum.

[NSNull null]a, tekil durumlarda boş değerlerini temsil etmek için nesnenin kullanımı nil(örneğin, bir, tipik olarak bir toplama nesnesi bir değer olarak yasaktır NSArrayveya NSDictionary). Sayı ve Değer Programlama Konuları: NSNull Kullanımı



4

Daha önce de belirtildiği gibi, bunlar aynı, ancak karşılık gelen çerçevenin yazıldığı dile bağlı olarak birini ya da diğerini kullanıyorum.

Objective-C ile ilgili her şey için nil kullanıyorum. Örneğin:

- (BOOL)doSomethingWithObjectsInArray:(NSArray *)anArray {
    if (anArray == nil) return NO;

    // process elements
    ...
}

Ancak, bir C-çerçevesinden (AddressBook çerçevesi ve CoreFoundation gibi) veri modellerinin geçerliliğini kontrol ederken, NULL kullanıyorum. Örneğin:

- (BOOL)showABUnknownPersonVCForABRecordRef:(ABRecordRef)aRecord {
    if (aRecord == NULL) return NO;

    // set-up the ABUnknownPersonViewController and display it on screen
    ..
}

Bu şekilde, Obj-C veya C tabanlı kod ile uğraşıyorsam benim kod ince ipuçları var.


4

nil , hiçbir şeye nesne göstergesidir. Den semantik farklı olsa da NULL , bunlar teknik olarak eşdeğer birbirlerine.

Çerçeve düzeyinde, Foundation tek bir NSNull nesnesini döndüren bir sınıf yöntemi olan + null değerini tanımlayan NSNull'u tanımlar. NSNull farklıdır sıfır veya NULL bir olmasıyla, gerçek bir amacı yerine bir sıfır değerine göre,.

Ayrıca, Foundation / NSObjCRuntime.h dosyasında Nil , hiçbir şeye sınıf işaretçisi olarak tanımlanır .

Daha fazla bilgi için buna başvurun - nil / Nil / NULL / NSNull


3

Bazı bağlamlarda bir fark vardır.

Kelimenin tam anlamıyla, Null bir karakterdir: ASCII 0.

Nil, boşlukla eşdeğerdir, değer yoktur.

Programlama içeriğine bağlı olarak, bu büyük bir fark olabilir.


1

Örneğin, bir çıkış parametresi türüne (NSError **) sahip bir Objective-C yöntemi çağırdığınızda NULL kullanın.

Web'de insanların bu durumda null yerine nil sağladığı birçok örnek kod görüyorum. Bunun nedeni, bir işaretçiye işaretçi olmasıdır ve bu nedenle doğrudan bir Objective-C nesne türü değildir. Yukarıda belirtildiği gibi, Objective-C nesne türleri için sıfır kullanılmalıdır.


1

Temel olarak: nil: bir nesnede null işaretçisi ve null: diğer tip işaretçisi içindir


0

nil, değerin yokluğu anlamına gelirken NULL, Nesne Yok'u temsil eder,

NSArray * dizi = @ [@ "Merhaba Dünya!", @ 101, [NSNULL null]];

Burada [NSNULL null], hiçbir nesne olmadığı anlamına gelen bir nesnedir, aynı zamanda nesnenin yokluğunu göstermek için nil ekleyemezsiniz.

kontrol için hem nil hem de [NSNUll null] kullanabilirsiniz.


0

Bu, nil, NIL ve null arasındaki farkı anlamanıza yardımcı olacaktır.

Aşağıdaki bağlantı bir şekilde size yardımcı olabilir:

http://nshipster.com/nil/

nil -> Objective-C nesneleri için değişmez boş değer.

Nil -> Objective-C sınıfları için gerçek null değer.

NULL -> C işaretçileri için gerçek null değer.

NSNULL -> null değerini temsil etmek için kullanılan singleton nesnesi.


bu yeni bir şey ekliyor mu (mevcut cevapların kapsamına girmeyen)?
Florian Koch
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.