我試圖沿着線的東西:Objective-C是否使用短路評估?
if(myString != nil && myString.length) { ... }
,並得到:
- [NSNull長]:發送到實例無法識別選擇
是否Objective-C的不短路後的第一個條件失敗?
我試圖沿着線的東西:Objective-C是否使用短路評估?
if(myString != nil && myString.length) { ... }
,並得到:
- [NSNull長]:發送到實例無法識別選擇
是否Objective-C的不短路後的第一個條件失敗?
的Objective-C不支持短路評價,就像C.
看來,在你的榜樣myString
是NSNull
而不是nil
,因此myString != nil
是真實的。
NSNull是一個單例,用於表示只允許對象的nil
,例如在NSArray中。
順便說一句,通常,人們寫if (!myString && myString.length == 0)
。相比nil
是相當難看的。另外,我會將長度與0進行比較。這似乎更清楚。
Objective-C中是C.
的嚴格的超由於C支持短路評價,Objective-C的不爲好。
NString * str = expressionThatReturnsStrOrNil()|| @ 「」;不起作用。這是短路評估不起作用。 – 2012-09-12 11:51:36
@PedroMorteRolo:當然可以。你期望什麼結果? (請記住'||'運算符的結果不是'1'或'0',絕不是其他)。 – 2012-09-12 12:02:13
你說得對。我錯誤地認爲C具有與Ruby相同的語義。 – 2012-09-13 09:03:38
什麼是NSNull定義爲?如果它是一個本不應該代表什麼的對象,那它就不會是零。換句話說,NSNull和nil是不一樣的。
如果你有一個NSNull的地方,你可能使用JSON解析器或CoreData。當沒有設置CoreData中的數字時,CoreData會讓你回到NSNull - 對於CoreData中的NSString值也可能是相同的。
同樣,你可以在從服務器返回的JSON中有空元素,一些解析器會給你作爲一個NSNull對象。所以在這兩種情況下,當你使用值時你必須小心,因爲你認爲是NSString或NSNumber對象的東西實際上是NSNull。
一個解決方案是在NSNull上定義一個類別,它僅僅忽略發送給該對象的所有不理解的消息,如下面的代碼所示。然後你的代碼會工作,因爲NSNull.length將返回0.你可以在你的項目.pch文件中包含類似這樣的東西,它將被包含在項目中的每個文件中。
// NSNull+IgnoreMessages.h
@interface NSNull(IgnoreMessages)
- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
@end
//NSNull+IgnoreMessages.m
#import "NSNull+IgnoreMessages.h"
@implementation NSNull(IgnoreMessages)
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([self respondsToSelector:[anInvocation selector]])
[anInvocation invokeWithTarget:self];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature *sig=[[NSNull class] instanceMethodSignatureForSelector:aSelector];
// Just return some meaningless signature
if(sig==nil)
sig=[NSMethodSignature signatureWithObjCTypes:"@^v^c"];
return sig;
}
@end
這只是等待失敗。知道何時處理'NSNull'而不是'nil'很重要,你的代碼使得這種情況不太可能發生。在問題的例子中,有一個錯誤信息包含'NSNull',你不會在你的代碼中看到這個錯誤信息,並且'if(myString)'仍然會評估爲true。 – 2010-01-14 11:09:54
那麼告訴我,如果你可以發送任何消息給它,它就像nil一樣會失敗,它仍然會調用NSNull(包括所有的NSObject方法)實際理解的任何消息。 現在它可能會導致錯誤,因爲如果你明確地檢查等於零,這將是不正確的。但在大多數編碼中,完全是因爲nil可以發送任何消息,我只是在類似於(myString.length> 0)的情況下進行測試,在這裏可以正常工作。事實上,當一個NSNull滑入你不期望的地方時,這段代碼將會阻止你的代碼崩潰,所以平衡它是一個穩定增益。 – 2010-01-14 15:41:13
另外,它說的是一個錯誤消息?這甚至沒有任何意義,爲什麼任何想發回錯誤消息的地方都會發送NSNull來代替NSString?在實踐中,我只見過NSNull從CoreData和一些JSON解析器中走出來,這種測試除了防止非明顯的運行時錯誤外什麼都不做。你仍然可以檢查NSNull的重要位置。 – 2010-01-14 15:45:34
'NSNull'等於'nil'嗎? – 2010-01-13 22:28:56
不是。 NSNull和零不是一回事。一點也不。 – bbum 2010-01-13 22:47:58