เมื่อใดที่ฉันควรใช้ nil และ NULL ใน Objective-C


170

นี่คือตัวอย่างรหัส:

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]");

เมื่อใดที่ฉันควรใช้ nil, NULL และ [NSNull null]?


4
มันเกี่ยวข้องกับคำถาม Objective C
Biranchi

nilหมายถึงชนิดของNULLอินสแตนซ์ objc ดังนั้นคุณสามารถทำเครื่องหมายค่าเฉพาะนั้นมีไว้สำหรับอินสแตนซ์ objc หรือตัวชี้ทั่วไป ในมุมมองของการจัดการประเภทและความปลอดภัยสิ่งนี้จะช่วยคุณได้มาก
eonil

4
nilและnull/ NULLเหมือนกัน - ทั้งคู่ถูกกำหนดให้เป็นศูนย์ เป็นแบบแผนใช้nilเมื่อเขียนโค้ด Objective-C และNULLเมื่อโค้ด C / C ++ ข้อความ / การโทรปกติ NSNullเป็นสิ่งที่แตกต่างอย่างสิ้นเชิงอย่างไรก็ตาม มันเป็นวัตถุซิงเกิลตันที่ทำหน้าที่เป็นตัวยึดตำแหน่งเพื่อแทน "nothing" ในเช่น NSDictionarys ที่ไม่อนุญาตพอยน์เตอร์ / null
Licks ร้อน

อ้างอิงลิงค์สำหรับคำอธิบายที่ดี [ที่นี่] [1] [1]: stackoverflow.com/questions/5908936//
Ameer

1
เป็นไปได้ซ้ำของNULL vs nil ใน Objective-C
awiebe

คำตอบ:


114

คุณสามารถใช้nilเกี่ยวกับทุกที่ที่คุณสามารถnullใช้ได้ ความแตกต่างที่สำคัญคือคุณสามารถส่งข้อความถึงnilคุณจึงสามารถใช้ในบางสถานที่ที่nullไม่สามารถทำงานได้

nilโดยทั่วไปใช้เพียงแค่


12
ในทางเทคนิคพวกมันเท่ากันคุณสามารถส่งข้อความไปยังทั้งศูนย์และไปที่ศูนย์ ปกติแม้ว่าไม่มีศูนย์มักจะใช้เพื่อเป็นตัวแทนของวัตถุ
cobbal

41
นอกจากนี้ยังมีใน MacTypes.h มี#define nil NULL
cobbal

8
ใช่อย่างที่ cobbal บอกไว้พวกมันเหมือนกัน มันเป็นมากกว่าการอ้างอิงตามบริบทที่ NULL เป็นตัวชี้ไปที่ 0x0, ไม่มีเป็นวัตถุที่ไม่มีวัตถุประสงค์ -c และไม่มีเป็นวัตถุคลาส -c วัตถุประสงค์ แต่ในทางเทคนิคพวกเขาทั้งหมดเพียง 0 นอกจากนี้มันเป็นโมฆะไม่ null - null อยู่ใน Java หรือ C # แต่ไม่ใช่ใน Objective-C
เจสันโคโค่

16
คำตอบที่ยอมรับนี้ล้มเหลวในการยอมรับว่า[NSNull null]เป็นสัตว์ที่แตกต่างกันมาก ในการอ้างอิงจากการอ้างอิงคลาสของ NSNull "คลาส NSNull จะกำหนดวัตถุเดี่ยวที่ใช้เพื่อแสดงค่า Null ในวัตถุคอลเลกชัน (ซึ่งไม่อนุญาตให้มีค่าศูนย์)" ดูที่การใช้ส่วนNSNullของหัวข้อการเขียนโปรแกรมจำนวนและค่า
Rob

"ความแตกต่างที่สำคัญคือคุณสามารถส่งข้อความไปยังศูนย์" - คุณสามารถส่งข้อความถึงได้NULLเช่นกัน

313

พวกเขาแตกต่างกันในประเภทของพวกเขา พวกมันทั้งหมดเป็นศูนย์ แต่NULLเป็น a void *, nilเป็นidและNilเป็นตัวชี้คลาส


14
คำอธิบายที่ดีที่สุดที่ฉันเคยได้ยินเกี่ยวกับความแตกต่าง (: ขอบคุณ
Jacob

3
นี่ควรเป็นคำตอบที่ยอมรับไม่ใช่เพราะมีการโหวตมากขึ้น แต่เพราะมันมีคำอธิบายที่ดีที่สุดสำหรับคำถามที่โพสต์
James Mertz

5
คำอธิบายที่สง่างามของNULLv nilแต่นี่เป็นเรื่องที่[NSNull null]สำคัญมาก ดูการใช้ NSNullส่วนของจำนวนและมูลค่าหัวข้อการเขียนโปรแกรมและNSNull ชั้นอ้างอิง
Rob

void *ทั้งสองดูเหมือนจะชี้ไปยัง คำตอบที่แตกต่างกันที่นี่แล้วกล่าวถึงนี้ แต่ถ้าคุณขุดลงไปคุณจะพบเส้นobjc.h #define nill __DARWIN_NULL
gkb0986

1
คำตอบนี้ฟังดูดี แต่ตามคำตอบอื่น ๆ มันไม่ถูกต้อง
n13

30

nilเป็นค่าว่างที่ถูกผูกไว้ / สอดคล้องกับวัตถุ (ชนิด id ใน Objective-C) ศูนย์ได้ไม่มีการอ้างอิง / ที่อยู่เพียงค่าว่าง

NSString *str = nil;

ดังนั้นควรใช้ศูนย์ถ้าเราจัดการกับวัตถุ

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

ตอนนี้NULLใช้สำหรับตัวชี้ที่ไม่ใช่วัตถุ (เช่นตัวชี้ C) ใน Objective-C เช่นเดียวกับศูนย์ , โมฆะได้ค่ามิได้ไม่มีที่อยู่

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

ดังนั้นหากมีสถานการณ์เมื่อฉันต้องการตรวจสอบstructของฉัน(ตัวแปรชนิดโครงสร้าง) ว่างเปล่าหรือไม่ฉันจะใช้:

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

เรามีอีกตัวอย่างหนึ่ง

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

จากการสังเกตค่าคีย์บริบทควรเป็นตัวชี้ C หรือการอ้างอิงวัตถุ ที่นี่สำหรับบริบทที่เราไม่สามารถใช้ศูนย์ ; เราจะต้องใช้เป็นโมฆะ

ในที่สุดชั้นNSNullกำหนดวัตถุเดี่ยวที่ใช้ในการเป็นตัวแทนค่า null ในวัตถุที่เก็บรวบรวม (NSArray, NSDictionary) [NSNull null]จะผลตอบแทนเช่นเดี่ยวของ NSNull โดยทั่วไป[NSNull null]เป็นวัตถุที่เหมาะสม

ไม่มีวิธีการแทรกวัตถุไม่มีลงในวัตถุชนิดคอลเลกชัน ลองมาตัวอย่าง:

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

ในบรรทัดที่สองเราจะไม่ได้รับข้อผิดพลาดใด ๆ เนื่องจากเป็นการดีที่จะแทรกวัตถุ NSNull ลงในวัตถุประเภทคอลเลกชัน ในบรรทัดที่สามเราจะได้รับข้อผิดพลาด "object cannot be nil" เพราะไม่มีวัตถุ


+1 สำหรับการกล่าวถึงการใช้งานจริงของศูนย์ / โมฆะในอาร์เรย์
Michael

19

NULL และ nil มีค่าเท่ากัน แต่ nil เป็นค่าวัตถุในขณะที่ NULL เป็นค่าตัวชี้ทั่วไป ( (void*)0เป็นค่าเฉพาะ) [NSNull null]เป็นวัตถุที่ตั้งใจให้เป็นศูนย์ในสถานการณ์ที่ไม่ได้รับอนุญาต ตัวอย่างเช่นคุณไม่สามารถมีค่าศูนย์ใน NSArray ดังนั้นหากคุณต้องการจะเป็นตัวแทนของ "ศูนย์" [NSNull null]คุณสามารถใช้


12

ฉันพบสิ่งต่อไปนี้:

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 */

ลักษณะที่ปรากฏไม่มีความแตกต่าง แต่เป็นแนวคิด



7

พวกเขาทั้งสองเป็นเพียง typecast ศูนย์ของ หน้าที่ไม่มีความแตกต่างระหว่างพวกเขา เช่น.

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

มีความแตกต่าง แต่สำหรับตัวคุณเองและคนอื่น ๆ ที่อ่านรหัสเท่านั้นคอมไพเลอร์ไม่สนใจ

อีกสิ่งหนึ่งไม่มีคือค่าวัตถุในขณะที่ NULL เป็นค่าตัวชี้ทั่วไป


6

ใน OS X และ iOS SDK ที่ทันสมัย:

  • nilและNilและNULLเหมือนกันใน Objective-C และใน Objective-C ++ ก่อน C ++ 11
  • nilและNilและstd::nullptrเหมือนกันใน Objective-C ++ กับ C ++ 11

โวหารหลายคนชอบที่จะใช้nilสำหรับวัตถุ Objective-C และNULLหรือnullptrประเภทตัวชี้อื่น ๆ ตอนนี้ฉันเองก็ใช้nilทุกที่

[NSNull null]เป็นวัตถุซิงเกิลตันที่ใช้เพื่อแสดงค่า Null ในสถานการณ์ที่nilห้ามมิให้เป็นค่า (โดยทั่วไปจะเป็นวัตถุการรวบรวมเช่นNSArrayหรือ NSDictionary) จำนวนและหัวข้อการเขียนโปรแกรมค่า: การใช้ NSNull



4

ดังที่ได้กล่าวมาแล้วพวกเขาเหมือนกัน แต่ฉันใช้อย่างใดอย่างหนึ่งหรืออื่น ๆ ขึ้นอยู่กับภาษาที่มีการเขียนกรอบที่เกี่ยวข้อง

สำหรับทุกอย่างที่เกี่ยวข้องกับ Objective-C ฉันใช้ศูนย์ ตัวอย่างเช่น:

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

    // process elements
    ...
}

อย่างไรก็ตามเมื่อตรวจสอบความถูกต้องของตัวแบบข้อมูลจาก C-framework (เช่น AddressBook Framework และ CoreFoundation) ฉันใช้ NULL ตัวอย่างเช่น:

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

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

วิธีนี้ฉันมีปมละเอียดในรหัสของฉันถ้าฉันจัดการกับรหัสตาม Obj-C หรือ C


4

ไม่มีเป็นตัวชี้วัตถุเพื่ออะไร แม้ว่า semantically จะแตกต่างจากNULLแต่ในทางเทคนิคจะเทียบเท่ากัน

ในระดับกรอบมูลนิธิกำหนดNSNullซึ่งกำหนดวิธีการเรียน + null ซึ่งส่งกลับวัตถุ NSNull เดี่ยว NSNullแตกต่างจากศูนย์หรือNULLซึ่งเป็นวัตถุจริง แทนที่จะเป็นค่าศูนย์

นอกจากนี้ใน Foundation / NSObjCRuntime.h Nilจะถูกกำหนดเป็นตัวชี้คลาส ให้เป็นค่าเริ่มต้น

อ้างถึงนี้สำหรับข้อมูลเพิ่มเติม - nil / Nil / NULL / NSNull


3

มีความแตกต่างในบางบริบท

ตัวอักษร Null เป็นตัวอักษร: ASCII 0

Nil เทียบเท่ากับช่องว่างไม่มีค่า

ขึ้นอยู่กับบริบทการเขียนโปรแกรมซึ่งอาจแตกต่างกันมาก


1

ใช้ NULL ตัวอย่างเช่นเมื่อคุณเรียกใช้เมธอด Objective-C พร้อมกับพารามิเตอร์เอาต์พุตเป็นชนิด (NSError **)

ฉันเห็นโค้ดตัวอย่างจำนวนมากบนเว็บที่มีคนให้เป็นศูนย์แทน NULL ในกรณีนี้ นี่เป็นเพราะมันเป็นตัวชี้ไปยังตัวชี้และไม่ใช่ประเภทวัตถุ Objective-C โดยตรง ดังที่ได้กล่าวไว้ข้างต้นควรใช้ศูนย์สำหรับประเภทวัตถุ Objective-C


1

โดยพื้นฐาน: ไม่มี: ตัวชี้โมฆะบนวัตถุและเป็นโมฆะ: สำหรับตัวชี้ประเภทอื่น ๆ


0

nil หมายถึงการขาดค่าในขณะที่ NULL แสดงว่าไม่มีวัตถุ

NSArray * array = @ [@ "Hello World!", @ 101, [NSNULL null]];

ที่นี่ [NSNULL null] เป็นวัตถุที่หมายถึงไม่มีวัตถุในเวลาเดียวกันคุณไม่สามารถเพิ่มศูนย์เพื่อระบุว่าไม่มีวัตถุ

คุณสามารถใช้ทั้งศูนย์และ [NSNUll null] เพื่อตรวจสอบได้เช่นกัน


0

สิ่งนี้จะช่วยให้คุณเข้าใจความแตกต่างระหว่างศูนย์, ศูนย์และศูนย์

ลิงค์ด้านล่างอาจช่วยคุณในบางวิธี:

http://nshipster.com/nil/

nil -> ค่า null ตามตัวอักษรสำหรับ Objective-C

ไม่มี -> ค่า null ตามตัวอักษรสำหรับคลาส Objective-C

NULL -> ค่า null ตามตัวอักษรสำหรับ C พอยน์เตอร์

NSNULL -> วัตถุ singleton ที่ใช้แทนค่า null


นี้จะเพิ่มอะไรใหม่ (ซึ่งไม่ครอบคลุมโดยคำตอบที่มีอยู่)?
Florian Koch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.