私は次の行に沿って何かを試しました:
if(myString != nil && myString.length) { ... }
そして得た:
-[NSNull 長さ]: 認識されないセレクターがインスタンスに送信されました
最初の条件が失敗した後、Objective-C は短絡しませんか?
私は次の行に沿って何かを試しました:
if(myString != nil && myString.length) { ... }
そして得た:
-[NSNull 長さ]: 認識されないセレクターがインスタンスに送信されました
最初の条件が失敗した後、Objective-C は短絡しませんか?
Objective-C は、C と同様に短絡評価をサポートしています。
あなたの例myString
では is NSNull
and notnil
であるように思われるため、myString != nil
真です。
NSNullはシングルトンでありnil
、NSArray など、オブジェクトのみが許可されている場所を表すために使用されます。
ところで、通常、人々はif (!myString && myString.length == 0)
. との比較nil
はかなり醜いです。また、長さを 0 と比較します。
Objective-C は C の厳密なスーパーセットです。
C は短絡評価をサポートしているため、Objective-C も同様にサポートしています。
NSNull は何と定義されていますか? それが何も表現しないはずのオブジェクトである場合、それは nil ではありません。つまり、NSNull と nil は同じではありません。
どこかに NSNull がある場合は、JSON パーサーまたは CoreData を使用している可能性があります。CoreData の数値が設定されていない場合、CoreData は NSNull を返します。おそらく、CoreData の NSString 値についても同じことが言えます。
同様に、サーバーから返された JSON に空の要素を含めることができ、一部のパーサーはそれを NSNull オブジェクトとして提供します。したがって、どちらの場合も、NSString または NSNumber オブジェクトだと思っていたものが実際には NSNull であるため、値を使用するときは注意が必要です。
1 つの解決策は、以下のコードのように、オブジェクトに送信されたすべての理解できないメッセージを単純に無視するカテゴリを 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