18

私は次の行に沿って何かを試しました:

if(myString != nil && myString.length) { ... }

そして得た:

-[NSNull 長さ]: 認識されないセレクターがインスタンスに送信されました

最初の条件が失敗した後、Objective-C は短絡しませんか?

4

4 に答える 4

30

Objective-C は、C と同様に短絡評価をサポートしています。

あなたの例myStringでは is NSNulland notnilであるように思われるため、myString != nil真です。

NSNullはシングルトンでありnil、NSArray など、オブジェクトのみが許可されている場所を表すために使用されます。

ところで、通常、人々はif (!myString && myString.length == 0). との比較nilはかなり醜いです。また、長さを 0 と比較します。

于 2010-01-13T22:28:53.140 に答える
10

Objective-C は C の厳密なスーパーセットです。

C は短絡評価をサポートしているため、Objective-C も同様にサポートしています。

于 2010-01-13T22:28:38.447 に答える
3

NSNull は何と定義されていますか? それが何も表現しないはずのオブジェクトである場合、それは nil ではありません。つまり、NSNull と nil は同じではありません。

于 2010-01-13T22:28:48.903 に答える
0

どこかに 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
于 2010-01-14T01:01:46.397 に答える