2013-05-17 37 views
13

Dưới đây là một khối mã, nghĩa vụ phải kiểm tra xem một từ điển có rỗng hay không, và nếu không, hãy rút ra đối tượng đúng. Tuy nhiên, vì một lý do nào đó, mặc dù việc kiểm tra if không thành công, mã vẫn thực thi. Có một số quirk với cách NSNull hoạt động mà tôi không hiểu, hoặc đây là một lỗi của Apple?Kiểm tra sự bình đẳng với NSNull

if (svcUser && !(svcUser == (id)[NSNull null])) { 
    return [svcUser objectForKey:@"access_level"]; 
} 

điều khiển phản ứng:

(lldb) print svcUser && !(svcUser == (id)[NSNull null]) 
(bool) $0 = false 
(lldb) continue 
-[NSNull objectForKey:]: unrecognized selector sent to instance 0x2b51678 
+4

Hãy thử phá vỡ các ngoại lệ và đảm bảo rằng "công cụ chọn không được nhận ra" đang được ném vào nơi bạn cho rằng đó là http://developer.apple.com/library/mac/recipes/xcode_help- breakpoint_navigator/articles/adding_an_exception_breakpoint.html –

+0

Bạn đã bao giờ tìm ra những gì đang xảy ra ở đây? –

+0

Lời giải thích dứt khoát ---> http://nshipster.com/nil/ –

Trả lời

18

NSNull là một lớp. Và giống như với tất cả các lớp học, bạn phải sử dụng isEqual:, không phải == để xem liệu hai đối tượng có biểu thị cùng một giá trị hay không.

if (svcUser && ![svcUser isEqual:[NSNull null]]) { 
    return [svcUser objectForKey:@"access_level"]; 
} 
+7

Có, nhưng '[NSNull null]' là một đối tượng đơn lẻ, vì vậy bạn có thể kiểm tra nó theo một trong hai cách, vì chúng sẽ được tham chiếu bằng nhau. Như bạn có thể nói từ đầu ra của giao diện điều khiển, logic 'if' là tốt, nhưng bằng cách nào đó khối mã vẫn đang được thực thi. – jungziege

+1

Tôi cảm thấy như tôi đã luôn luôn sử dụng '==' thành công cho 'NSNull'. [Mã mẫu] của Apple (http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/NumbersandValues/Articles/Null.html#//apple_ref/doc/uid/TP40005153-SW1) dường như thậm chí xác nhận so sánh này. –

+2

Nhưng đó là chi tiết triển khai mà bạn không nên dựa vào. Sử dụng 'isEqual:' là tốt hơn và an toàn hơn là dựa vào '==' làm việc. Điều này đã đốt cháy rất nhiều người trong quá khứ khi so sánh các chữ 'NSString'. @jungziege - chỉ là một kiểm tra sanity nhưng bạn có chắc chắn 100% rằng vụ tai nạn là trong dòng đăng của mã và không phải ở nơi khác? – rmaddy

8

Bạn có thể kiểm tra xem nó bằng cách sử dụng:

if(![svcUser isKindOfClass:[NSNull class]]){ 
    return [svcUser objectForKey:@"access_level"]; 
} 
+0

lý do bỏ phiếu xuống? – Joshua

+1

Nếu 'svcUser' thực sự là một đối tượng' NSNull', gọi 'count' trên nó sẽ gây ra sự cố. Ngoài ra, mục tiêu là để chắc chắn nó là * không * một đối tượng 'NSNull'. Và 'nsnull' là gì? – rmaddy

+0

Ngoài ra, sử dụng '==' để so sánh hai đối tượng không chính xác. Bạn cần sử dụng 'isEqual:' để so sánh hai đối tượng. – rmaddy

26

Đơn giản chỉ cần kiểm tra:

svcUser == [NSNull null] 

Đây là phương pháp mà Apple đề cập đến trong docs của họ.

+3

Điều này đã cho tôi một cảnh báo, sử dụng http://stackoverflow.com/a/22825611/62 để ngăn chặn nó. –

6

Sử dụng cách tiếp cận @ JE42 cho tôi cảnh báo về Xcode 5.1. Thay vào đó, hãy cast:

(id)svcUser == [NSNull null] 
Các vấn đề liên quan