web-dev-qa-db-ja.com

NSArray内のオブジェクトがNSNullかどうかを確認するにはどうすればよいですか?

Null値の配列を取得しています。以下の私の配列の構造を確認してください:

 (
    "< null>"
 )

インデックス0にアクセスしようとすると、

-[NSNull isEqualToString:]: unrecognized selector sent to instance 0x389cea70

現在、クラッシュログを含むその配列のためにクラッシュしています:

 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull isEqualToString:]: unrecognized selector sent to instance 0x389cea70'
*** First throw call stack:
(0x2d9fdf53 0x3820a6af 0x2da018e7 0x2da001d3 0x2d94f598 0x1dee57 0x1dfd31 0x302f598d 0x301a03e3 0x3052aeed 0x3016728b 0x301659d3 0x3019ec41 0x3019e5e7 0x30173a25 0x30172221 0x2d9c918b 0x2d9c865b 0x2d9c6e4f 0x2d931ce7 0x2d931acb 0x3262c283 0x301d3a41 0xabb71 0xabaf8)
libc++abi.dylib: terminating with uncaught exception of type NSException
61
Navi
id object = myArray[0];// similar to [myArray objectAtIndex:0]

if(![object isEqual:[NSNull null]])
{
    //do something if object is not equals to [NSNull null]
}
118
if (myArray != (id)[NSNull null])

OR

if(![myArray isKindOfClass:[NSNull class]]) 
30

Toniの回答を基に、マクロを作成しました。

#define isNSNull(value) [value isKindOfClass:[NSNull class]]

それからそれを使用する

if (isNSNull(dict[@"key"])) ...
13
respectTheCode

Awww、みんな。これは簡単です。

// if no null values have been returned.
if ([myValue class] == [NSNull class]) {
    myValue = nil;
}

より良い答えがあると確信していますが、これはうまくいきます。

7
Alex Zavatone

NSNullを操作するコードには次の問題があることがわかりました。

  • うるさくてい。
  • 時間がかかる。
  • エラーを起こしやすい。

そこで、次のカテゴリを作成しました。

@interface NSObject (NSNullUnwrapping)

/**
* Unwraps NSNull to nil, if the object is NSNull, otherwise returns the object.
*/
- (id)zz_valueOrNil;

@end

実装時:

@implementation NSObject (NSNullUnwrapping)

- (id)zz_valueOrNil
{
    return self;
}

@end

@implementation NSNull (NSNullUnwrapping)

- (id)zz_valueOrNil
{
    return nil;
}

@end

次のルールで動作します:

  • 同じClass(つまりClass型のシングルトンインスタンス)に対してカテゴリが2回宣言されている場合、動作は未定義です。ただし、サブクラスで宣言されたメソッドは、そのスーパークラスのカテゴリメソッドをオーバーライドできます。

これにより、より簡潔なコードが可能になります

[site setValue:[resultSet[@"main_contact"] zz_valueOrNil] forKey:@"mainContact"];

。 。 NSNullを確認するための余分な行があるのとは対照的です。 zz_プレフィックスは少しいように見えますが、名前空間の衝突を避けるために安全のためにあります。

6
Jasper Blues

多くの良い、興味深い答えがすでに与えられており、(必要に応じて)それらのすべてが機能します。

完成のために(そしてその楽しみ):

[NSNull null]は、シングルトンを返すように文書化されています。だから

if (ob == [NSNull null]) {...} 

うまく動作します。

ただし、これは例外であるため、オブジェクトの比較に==を使用することは一般的に良い考えだとは思いません。 (私があなたのコードをレビューするなら、私は確かにこれについてコメントするでしょう)。

3
Hermann Klecker

Swift(またはObjective-Cからのブリッジ)では、オプションの配列にNSNullnilを含めることができます。 NSArraysにはオブジェクトのみを含めることができ、nilを持つことはありませんが、NSNullを持つことはできます。ただし、Swift Any?型の配列には、nilを含めることができます。

let myArray: [Any?] = [nil, NSNull()] // [nil, {{NSObject}}], or [nil, <null>]

NSNullに対してチェックするには、isを使用してオブジェクトのタイプをチェックします。このプロセスは、Swift配列およびNSArrayオブジェクトでも同じです。

for obj in myArray {
    if obj is NSNull {
        // object is of type NSNull
    } else {
        // object is not of type NSNull
    }
}

if letまたはguardを使用して、オブジェクトをNSNullにキャストできるかどうかを確認することもできます。

guard let _ = obj as? NSNull else {
    // obj is not NSNull
    continue;
}

または

if let _ = obj as? NSNull {
    // obj is NSNull
}
2
JAL

このアプローチを検討してください:

オプション1:

NSString *str = array[0];

if ( str != (id)[NSNull null] && str.length > 0 {
    // you have a valid string.
} 

オプション2:

NSString *str = array[0];
str = str == (id)[NSNull null]? nil : str;

if (str.length > 0) {
   // you have a valid string.
} 
2
Wayne

次のチェックを使用できます。

if (myArray[0] != [NSNull null]) {
    // Do your thing here
}

この理由は、Appleの公式ドキュメントに記載されています。

NSNullを使用する

NSNullクラスは、nilが値として禁止されている状況(通常、配列や辞書などのコレクションオブジェクト)でnull値を表すために使用するシングルトンオブジェクトを定義します。

NSNull *nullValue = [NSNull null];
NSArray *arrayWithNull = @[nullValue];
NSLog(@"arrayWithNull: %@", arrayWithNull);
// Output: "arrayWithNull: (<null>)"

NSNullインスタンスはNOまたはfalseと意味的に異なることを理解することが重要です。これらは両方とも論理値を表します。 NSNullインスタンスは、値がないことを表します。 NSNullインスタンスは意味的にnilと同等ですが、nilと等しくないことを認識することも重要です。したがって、nullオブジェクト値をテストするには、オブジェクトを直接比較する必要があります。

id aValue = [arrayWithNull objectAtIndex:0];
if (aValue == nil) {
    NSLog(@"equals nil");
}
else if (aValue == [NSNull null]) {
    NSLog(@"equals NSNull instance");
    if ([aValue isEqual:nil]) {
        NSLog(@"isEqual:nil");
    }
}
// Output: "equals NSNull instance"

https://developer.Apple.com/library/content/documentation/Cocoa/Conceptual/NumbersandValues/Articles/Null.html から取得

1
Marky