NSNumberオブジェクトがnilまたは空かどうかを確認するにはどうすればよいですか?
OK nilは簡単です:
NSNumber *myNumber;
if (myNumber == nil)
doSomething
しかし、オブジェクトが作成されたが、割り当てが失敗したためにオブジェクトに値がない場合、これを確認するにはどうすればよいですか?このようなものを使用しますか?
if ([myNumber intValue]==0)
doSomething
利用可能なNSStringのように空でオブジェクトをテストするための一般的な方法はありますか(これを参照してください post )?
例1
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *emptyNumber = [dict objectForKey:@"emptyValue"];
emptyNumber
にはどの値が含まれていますか? emptyNumber
が空かどうかを確認するにはどうすればよいですか?
例2
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSString *myString = [dict objectForKey:@"emptyValue"];
if (myString == nil || [myString length] == 0)
// got an empty value
NSNumber *emptyNumber=nil;
emptyNumber
がnilに設定された後にこれを使用するとどうなりますか?
[emptyNumber intValue]
ゼロになりますか?
例3
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *myEmptyValue = [dict objectForKey:@"emptyValue"];
if (myEmptyValue == nil)
// NSLog is never called
NSLog(@"It is empty!");
このように、NSLogが呼び出されることはありません。 myEmptyValue
はnil
ではなく、NSNull
でもありません。それで、それは任意の数を含みますか?
NSValue
、NSNumber
、...は値から作成され、常に値を保持することになっています。 0
のような特定の値のテストは、使用している有効な値の範囲内にない場合にのみ機能します。
"invalid"または"not set"を表す値があり、nil
を使用できない場合、コードの操作がより簡単になるまれなケースです。 (たとえば、標準コンテナの場合)代わりに NSNull
を使用できます。
あなたの最初の例では、これは次のようになります:
[dict setValue:[NSNull null] forKey:@"emptyValue"];
if ([dict objectForKey:@"emptyValue"] == [NSNull null]) {
// ...
}
ただし、nil
を区別する必要がない限り(つまり、コンテナ内にない場合)、その値を挿入(または削除)することはできません。たとえば、"invalid":
if ([dict objectForKey:@"nonExistent"] == nil) {
// ...
}
2番目の例については、-intValue
は0
を返しますが、単にnil
にメッセージを送信すると0
が返されるためです。 。 0
を取得することもできます。以前にNSNumber
が0
に設定されていたintValue
の場合、これは有効な値である可能性があります。
すでに上で書いたように、0
あなたにとって有効な値ではないの場合にのみ、このようなことを行うことができます。 for yoに注意してください。何が最も効果的かは、要件によって異なります。
要約を試してみましょう:
オプション#1:
数値範囲のすべての値が必要ない場合は、1つ(0
または-1
または...)および-intValue
/...を使用して具体的に表すことができます"空"。これは明らかにあなたには当てはまりません。
オプション#2:
"empty":の場合、値をコンテナに保存したり、コンテナから削除したりしないでください。
// add if not empty:
[dict setObject:someNumber forKey:someKey];
// remove if empty:
[dict removeObjectForKey:someKey];
// retrieve number:
NSNumber *num = [dict objectForKey:someKey];
if (num == nil) {
// ... wasn't in dictionary, which represents empty
} else {
// ... not empty
}
ただし、これは、空のキーと存在しないキーまたは違法なキーの間に違いがないことを意味します。
オプション#3:
まれに、すべてのキーを辞書に保持し、"empty"を異なる値で表す方が便利な場合があります。 NSNumber
には"empty"の概念がないため、番号範囲の1つを使用できない場合は、別の方法で入力する必要があります。 Cocoaには、このような場合に備えてすでにNSNull
があります。
// set to number if not empty:
[dict setObject:someNumber forKey:someKey];
// set to NSNull if empty:
[dict setObject:[NSNull null] forKey:someKey];
// retrieve number:
id obj = [dict objectForKey:someKey];
if (obj == [NSNumber null]) {
// ... empty
} else {
// ... not empty
NSNumber *num = obj;
// ...
}
このオプションにより、"empty"、"not empty"、"not in the container"(例:不正なキー)を区別できるようになりました。
NSNumber
はnil
であるか、数字が含まれていて、間に何もありません。 「空」は特定のオブジェクトのセマンティクスに依存する概念であるため、一般的な空のチェックを探すことは意味がありません。
あなたの例に関しては、いくつかのことが起こっています:
NSMutableDictionary *hash = [NSMutableDictionary dictionary];
[hash setObject:@"" forKey:@"key"];
NSNumber *number = [hash objectForKey:@"key"];
NSLog(@"%i", [number intValue]);
NSLog
はここに0
を出力しますが、これはintValue
にNSString
メソッドがあるためです。メッセージをNSNumber
のみが実行できるものに変更すると、コードは失敗します。
NSLog(@"%i", [number unsignedIntValue]);
これはスローします:
-[NSCFString unsignedIntValue]: unrecognized selector sent to instance 0x303c
つまり、notハッシュから一般的な「空の」値を取得し、そこに保存したNSString
を取得するだけです。
空の(== nil
)NSNumber
があり、それにメッセージを送信すると、結果はゼロになります。これは、コードを単純化する単なる言語規則です。
(array != nil && [array count] == 0)
(someNumber == nil ? 0 : [someNumber intValue])
これに変わります:
([array count] == 0)
([someNumber intValue])
お役に立てれば。
Swift 2.0および解析:
var myNumber = yourArray!.objectForKey("yourColumnTitle")
if (myNumber == nil) {
myNumber = 0
}
私の場合、次のことを行う必要がありました。
let myNumberIntValue = myNumber!.intValue
辞書からオブジェクトを取得し、それがNSNumberになることを期待してから、nilオブジェクトを返すことは(少なくとも私にとっては)非常に一般的です。これが発生し、intValueを実行すると、クラッシュします。
クラッシュするよりもデフォルト値を取得したいので、nil保護を設定します。
1つの方法は次のとおりです。
-(int) intForDictionary:(NSDictionary *)thisDict objectForKey: (NSString *)thisKey withDefault: (int)defaultValue
{
NSNumber *thisNumber = [thisDict objectForKey:thisKey];
if (thisNumber == nil) {
return defaultValue;
}
return [thisNumber intValue];
}
そして、私はフロート用にそれと同じようなものを持っています。次に、少なくともデフォルト値を取得します。もう1つの方法は、nil保護のメソッドを作成することです。
-(NSNumber *)nilProtectionForNumber: (NSNumber *)thisNumber withDefault: (NSNumber *)defaultNumber
{
if (thisNumber) {
return thisNumber;
}
else
return defaultNumber;
}
あなたがこのように呼ぶもの:
NSNumber *value = [self nilProtectionForNumber:[dict objectForKey:keyThatShouldBeNSNumber] withDefault:[NSNumber numberWithInt:0]];
NSNumber
sは不変であり、ファクトリメソッドまたは数値を与える初期メソッドのいずれかでのみ作成できます。私の知る限り、0を数えない限り、「空の」NSNumberで終わることはできません。