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
id object = myArray[0];// similar to [myArray objectAtIndex:0]
if(![object isEqual:[NSNull null]])
{
//do something if object is not equals to [NSNull null]
}
if (myArray != (id)[NSNull null])
OR
if(![myArray isKindOfClass:[NSNull class]])
Toniの回答を基に、マクロを作成しました。
#define isNSNull(value) [value isKindOfClass:[NSNull class]]
それからそれを使用する
if (isNSNull(dict[@"key"])) ...
Awww、みんな。これは簡単です。
// if no null values have been returned.
if ([myValue class] == [NSNull class]) {
myValue = nil;
}
より良い答えがあると確信していますが、これはうまくいきます。
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_
プレフィックスは少しいように見えますが、名前空間の衝突を避けるために安全のためにあります。
多くの良い、興味深い答えがすでに与えられており、(必要に応じて)それらのすべてが機能します。
完成のために(そしてその楽しみ):
[NSNull null]は、シングルトンを返すように文書化されています。だから
if (ob == [NSNull null]) {...}
うまく動作します。
ただし、これは例外であるため、オブジェクトの比較に==を使用することは一般的に良い考えだとは思いません。 (私があなたのコードをレビューするなら、私は確かにこれについてコメントするでしょう)。
Swift(またはObjective-Cからのブリッジ)では、オプションの配列にNSNull
とnil
を含めることができます。 NSArray
sにはオブジェクトのみを含めることができ、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
}
このアプローチを検討してください:
オプション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.
}
次のチェックを使用できます。
if (myArray[0] != [NSNull null]) {
// Do your thing here
}
この理由は、Appleの公式ドキュメントに記載されています。
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"