Khi nào tôi nên sử dụng nil và NULL trong Objective-C?


170

Đây là mã mẫu:

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

Khi nào tôi nên sử dụng nil, NULL và [NSNull null]?


4
Nó liên quan đến câu hỏi khách quan C.
Biranchi

nilcó nghĩa là một loại NULLví dụ objc. Vì vậy, bạn có thể đánh dấu giá trị cụ thể được dành cho ví dụ objc hoặc con trỏ chung. Theo quan điểm của quản lý loại và an toàn, điều này sẽ giúp bạn rất nhiều.
eonil

4
nilnull/ NULLgiống nhau - cả hai đều được xác định bằng không. Là một hình thức, sử dụng nilkhi mã hóa Objective-C và NULLkhi mã hóa các câu lệnh / cuộc gọi C / C ++ thông thường. NSNulllà một cái gì đó hoàn toàn khác nhau, tuy nhiên. Đó là một đối tượng đơn lẻ đóng vai trò là người giữ chỗ để đại diện cho "không có gì" trong, ví dụ: NSDipedia nơi không cho phép con trỏ nil / null.
Licks nóng

Tham khảo liên kết để được giải thích tốt [tại đây] [1] [1]: stackoverflow.com/questions/5908936/ khăn
Ameer

1
bản sao có thể có của NULL vs nil trong Objective-C
awiebe

Câu trả lời:


114

Bạn có thể sử dụng nilvề bất cứ nơi nào bạn có thể sử dụng null. Sự khác biệt chính là bạn có thể gửi tin nhắn đến nil, vì vậy bạn có thể sử dụng nó ở một số nơi nullkhông thể làm việc.

Nói chung, chỉ cần sử dụng nil.


12
về mặt kỹ thuật, chúng hoàn toàn bằng nhau, bạn có thể gửi tin nhắn đến cả nil và NULL. Thành ngữ mặc dù nil thường được sử dụng để đại diện cho một đối tượng
cobbal

41
Ngoài ra, trong MacTypes.h có#define nil NULL
cobbal

8
Vâng, như cobbal nói, chúng giống nhau. Nó là một tài liệu tham khảo theo ngữ cảnh trong đó NULL là một con trỏ tới 0x0, nil là một đối tượng object-c không tồn tại và Nil là một lớp object-c không tồn tại, nhưng về mặt kỹ thuật chúng chỉ là 0. Ngoài ra, nó không phải là NULL null - null có trong Java hoặc C # nhưng không có trong Objective-C.
Jason Coco

16
Câu trả lời được chấp nhận này không thừa nhận đó [NSNull null]là một con thú rất khác. Để trích dẫn từ Tham chiếu lớp NSNull , "Lớp NSNull định nghĩa một đối tượng singleton được sử dụng để biểu diễn các giá trị null trong các đối tượng bộ sưu tập (không cho phép các giá trị nil)." Đồng thời xem phần Sử dụng phần NSNull của Chủ đề Lập trình Số và Giá trị.
Cướp

"Sự khác biệt chính là bạn có thể gửi tin nhắn đến nil" - bạn cũng có thể gửi tin nhắn đến NULL.

313

Họ khác nhau về loại hình của họ. Tất cả đều bằng không, nhưng NULLlà một void *, nillà một idNillà một con trỏ Lớp.


14
Giải thích tốt nhất tôi đã nghe về sự khác biệt (: Cảm ơn.
Jacob

3
Đây phải là câu trả lời được chấp nhận, không phải vì có nhiều lượt bình chọn hơn mà vì nó có lời giải thích tốt nhất cho câu hỏi được đặt ra.
James Mertz

5
Mô tả thanh lịch của NULLv nil, nhưng điều này nghiêm trọng bỏ lỡ đánh dấu lại [NSNull null]. Xem phần Sử dụng phần NSNull của Chủ đề lập trình số và giá trịTham chiếu lớp NSNull .
Cướp

Cả hai dường như là con trỏ đến void *. Một câu trả lời khác ở đây đã đề cập đến vấn đề này, nhưng nếu bạn tìm hiểu kỹ objc.h, bạn sẽ tìm thấy dòng này #define nill __DARWIN_NULL.
gkb0986

1
Câu trả lời này nghe có vẻ hay nhưng theo các câu trả lời khác thì đơn giản là không chính xác.
n13

30

nil là một giá trị rỗng bị ràng buộc / tương ứng với một đối tượng (loại id trong Objective-C). nil không có tài liệu tham khảo / địa chỉ, chỉ là một giá trị trống.

NSString *str = nil;

Vì vậy, nên sử dụng nil, nếu chúng ta đang làm việc với một đối tượng.

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

Bây giờ NULL được sử dụng cho con trỏ không đối tượng (như con trỏ C) trong Objective-C. Giống như nil , NULL không có giá trị cũng như địa chỉ.

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

Vì vậy, nếu có một tình huống, khi tôi cần kiểm tra struct (biến kiểu cấu trúc) của mình có trống hay không thì tôi sẽ sử dụng:

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

Hãy có một ví dụ khác,

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

Theo quan sát khóa-giá trị , bối cảnh phải là con trỏ C hoặc tham chiếu đối tượng. Ở đây cho bối cảnh chúng ta không thể sử dụng nil ; chúng ta phải sử dụng NULL .

Cuối cùng, lớp NSNull định nghĩa một đối tượng singleton được sử dụng để biểu diễn các giá trị null trong các đối tượng bộ sưu tập (NSArray, NSDipedia). Các [NSNull null] sẽ trả về dụ singleton của NSNull. Về cơ bản [NSNull null] là một đối tượng thích hợp.

Không có cách nào để chèn một đối tượng nil vào một đối tượng kiểu bộ sưu tập. Hãy có một ví dụ:

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

Trên dòng thứ hai, chúng tôi sẽ không gặp bất kỳ lỗi nào, vì việc chèn một đối tượng NSNull vào một đối tượng kiểu bộ sưu tập là hoàn toàn công bằng. Trên dòng thứ ba, chúng ta sẽ gặp lỗi "object could be nil". Bởi vì nil không phải là một đối tượng.


+1 để đề cập đến việc sử dụng thực tế của nil / null trong mảng.
Michael

19

NULL và nil bằng nhau, nhưng nil là một giá trị đối tượng trong khi NULL là một giá trị con trỏ chung ( (void*)0, cụ thể). [NSNull null]là một đối tượng có nghĩa là đứng yên trong tình huống không được phép. Ví dụ: bạn không thể có giá trị bằng 0 trong NSArray. Vì vậy, nếu bạn cần đại diện cho một "con số không", bạn có thể sử dụng [NSNull null].


12

Tôi đã tìm thấy như sau:

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

Nhìn bề ngoài, không có gì khác biệt ngoài một khái niệm.



7

Cả hai đều chỉ là typecast zero. Về mặt chức năng, không có sự khác biệt giữa chúng. I E.,

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

Có một sự khác biệt, nhưng chỉ với chính bạn và những người khác đọc mã, trình biên dịch không quan tâm.

Một điều nữa là không có giá trị đối tượng trong khi NULL là giá trị con trỏ chung.


6

Trong SDK OS X và iOS hiện đại:

  • nilNilNULLlà giống hệt nhau trong Objective-C và trong Objective-C ++ trước khi C ++ 11.
  • nilNilstd::nullptrlà giống hệt nhau trong Objective-C ++ với C ++ 11.

Về mặt phong cách, nhiều người thích sử dụng nilcho các đối tượng Objective-C và NULLhoặc nullptrcho các loại con trỏ khác. Bản thân tôi bây giờ sử dụng nilở mọi nơi.

[NSNull null]là một đối tượng singleton được sử dụng để biểu diễn các giá trị null trong các tình huống nilbị cấm làm giá trị (thường là trong một đối tượng bộ sưu tập, chẳng hạn như NSArrayhoặc NSDictionary). Chủ đề lập trình số và giá trị: Sử dụng NSNull



4

Như đã đề cập, chúng giống nhau, nhưng tôi sử dụng cái này hoặc cái kia tùy thuộc vào ngôn ngữ mà khung tương ứng được viết.

Đối với mọi thứ liên quan đến Objective-C, tôi sử dụng nil. Ví dụ:

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

    // process elements
    ...
}

Tuy nhiên, khi kiểm tra tính hợp lệ của các mô hình dữ liệu từ khung C (như khung địa chỉ và CoreFoundation), tôi sử dụng NULL. Ví dụ:

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

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

Bằng cách này, tôi có manh mối tinh tế trong mã của mình nếu tôi đang xử lý mã dựa trên Obj-C hoặc C.


4

nil là một con trỏ đối tượng không có gì. Mặc dù về mặt ngữ nghĩa khác biệt với NULL , chúng tương đương về mặt kỹ thuật với nhau.

Ở cấp độ khung, Foundation định nghĩa NSNull , định nghĩa một phương thức lớp, + null, trả về đối tượng NSNull singleton. NSNull khác với nil hoặc NULL , ở chỗ nó là một đối tượng thực tế , thay vì giá trị 0.

Ngoài ra, trong Foundation / NSObjCR nb.h, Nil được định nghĩa là một con trỏ lớp không có gì.

Tham khảo thông tin này để biết thêm thông tin - nil / Nil / NULL / NSNull


3

Có một sự khác biệt trong một số bối cảnh.

Theo nghĩa đen, Null là một nhân vật: ASCII 0.

Nil tương đương với trống, không có giá trị.

Tùy thuộc vào bối cảnh lập trình, đây có thể là một sự khác biệt lớn.


1

Sử dụng NULL chẳng hạn khi bạn gọi một phương thức Objective-C với tham số đầu ra thuộc loại (NSError **).

Tôi thấy rất nhiều mã ví dụ trên web nơi mọi người cung cấp nil thay vì NULL trong trường hợp này. Điều này là do nó là một con trỏ tới một con trỏ và do đó không trực tiếp là một loại đối tượng Objective-C. Như đã nói ở trên, nil nên được sử dụng cho các loại đối tượng Objective-C.



0

nil có nghĩa là không có giá trị trong khi NULL đại diện cho Không có đối tượng,

NSArray * mảng = @ [@ "Xin chào thế giới!", @ 101, [NSNULL null]];

Ở đây [NSNULL null] là một đối tượng có nghĩa là không có đối tượng, đồng thời bạn không thể thêm nil để biểu thị sự vắng mặt của đối tượng.

bạn có thể sử dụng cả nil và [NSNUll null] để kiểm tra.


0

Điều này sẽ giúp bạn hiểu được sự khác biệt giữa nil, NIL và null.

Liên kết dưới đây có thể giúp bạn theo một cách nào đó:

http://nshipster.com/nil/

nil -> giá trị null bằng chữ cho các đối tượng Objective-C.

Nil -> giá trị null bằng chữ cho các lớp Objective-C.

NULL -> giá trị null bằng chữ cho con trỏ C.

NSNULL -> đối tượng singleton được sử dụng để đại diện cho null.


điều này có thêm bất cứ điều gì mới (mà không có trong các câu trả lời hiện có) không?
Florian Koch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.