Porównaj ceny domen i usług IT, sprzedawców z całego świata

sprawdź, czy NSNumber jest pusty


Jak mogę sprawdzić, czy obiekt NSNumber ma wartość NULL lub jest pusty?
OK zero jest proste:
NSNumber *myNumber;
if (myNumber == nil)
doSomething

Ale jeśli obiekt został utworzony, ale nie ma w nim wartości, ponieważ przypisanie się nie powiodło, jak mogę to sprawdzić? Użyć czegoś takiego?
if ([myNumber intValue]==0)
doSomething

Czy istnieje ogólna metoda testowania obiektów pod kątem pustości, jak w przypadku NSString (zobacz to

szybki
http://www.wilshipley.com/blog ... .html
)?

Przykład 1

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:@"" forKey:@"emptyValue"];
NSNumber *emptyNumber = [dict objectForKey:@"emptyValue"];

Jaką wartość zawiera
emptyNumber
? Jak mogę sprawdzić, czy element
emptyNumber
jest pusty?

Przykład 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;

Co się stanie, jeśli użyję tego po ustawieniu wartości
emptyNumber
na zero?
[emptyNumber intValue]

Czy dostanę zero?

Przykład 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!");

Na przykład NSLog nigdy nie jest tak nazywany.
myEmptyValue
nie jest ani
nil
, ani
NSNull
. Więc zawiera dowolną liczbę?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zakłada się, że
NSValue
,
NSNumber
, ... są tworzone na podstawie wartości i zawsze ją zawierają. Testowanie określonej wartości, takiej jak
0
, działa tylko wtedy, gdy nie mieści się w zakresie prawidłowych wartości, z którymi pracujesz.
W rzadkich przypadkach, gdy praca z kodem jest łatwiejsza, jeśli masz wartość, która reprezentuje

"invalid"

lub

"not set"

i nie możesz użyć
nil
(na przykład ze standardowymi kontenerami), możesz użyć
NSNull
http://developer.apple.com/lib ... 3-SW1
zamiast tego.
W Twoim

pierwszy przykład

Może być:
[dict setValue:[NSNull null] forKey:@"emptyValue"];if ([dict objectForKey:@"emptyValue"] == [NSNull null]) {
// ...
}

Należy jednak pamiętać, że możesz po prostu wstawić (lub usunąć) tej wartości, jeśli nie musisz odróżnić
Nil
(tj. Nie w kontenerze) i powiedzmy

"invalid"

:
if ([dict objectForKey:@"nonExistent"] == nil) {
// ...
}

O

drugi przykład

wtedy
-intValue
daje
0
- ale po prostu dlatego, że wysłanie wiadomości do
nil
zwraca
0
. Możesz również uzyskać
0
, na przykład dla
NSNumber
, którego
intValue
zostało wcześniej ustawione na
0
, co może być prawidłową wartością .

Jak napisałem powyżej, możesz zrobić coś takiego tylko wtedy, gdy
0

nie jest prawidłową wartością dla Ciebie
... zauważ, że

Dla Was

to, co działa najlepiej, zależy wyłącznie od Twoich wymagań.
Pozwól mi spróbować

rozczarowanie

wynik:

Opcja 1:

Jeśli nie chcesz, aby wszystkie wartości należały do ​​zakresu liczb, możesz użyć jednej (
0
lub
-1
lub ...) i
-intValue
/. ..) dla określonego widoku

"empty"
... Oczywiście Ciebie to nie dotyczy.

Opcja 2:

Po prostu nie przechowujesz i nie usuwaj wartości z kontenera, jeśli jeśli oni

"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
}

Oznacza to jednak, że nie ma różnicy między pustymi kluczami a kluczami, które nigdy nie istnieją lub są nielegalne.

Opcja # 3:

W niektórych rzadkich przypadkach wygodniej jest przechowywać wszystkie klucze w słowniku i reprezentować

"empty"

o innym znaczeniu. Jeśli nie możesz użyć jednego z zakresu liczb, musimy umieścić coś innego, ponieważ
NSNumber
nie ma pojęcia

"empty"
. Cocoa ma już nsnoull dla takich przypadków:
// 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;
// ...
}

Teraz ta opcja pozwala odróżnić

"empty"

,

"not empty"

i

"not in the container"

(np. nielegalny klucz).
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

NSNumber
ma wartość
nil
lub zawiera liczbę, nic pomiędzy. „Pustka” to pojęcie, które zależy od semantyki konkretnego obiektu, dlatego nie ma sensu szukać ogólnego sprawdzenia pustki.
Jeśli chodzi o twoje przykłady, dzieje się tutaj kilka rzeczy:
NSMutableDictionary *hash = [NSMutableDictionary dictionary];
[hash setObject:@"" forKey:@"key"];
NSNumber *number = [hash objectForKey:@"key"];
NSLog(@"%i", [number intValue]);

NSLog
wyświetli tutaj
0
, ale tylko dlatego, że
NSString
ma metodę
intValue
. Jeśli zmienisz wiadomość na coś, co może zrobić tylko
NSNumber
, kod się nie powiedzie:
NSLog(@"%i", [number unsignedIntValue]);

To spowoduje:
-[NSCFString unsignedIntValue]: unrecognized selector sent to instance 0x303c

To znaczy, że ty

nie

otrzymujesz jakąś ogólną "pustą" wartość z powrotem z hasha, po prostu otrzymujesz
NSString
, który tam zapisałeś.
Gdy masz pusty (
== nil
)
NSNumber
i wysyłasz do niego wiadomość, wynikiem jest zero. To tylko konwencja językowa, która upraszcza kod:
(array != nil && [array count] == 0)
(someNumber == nil ? 0 : [someNumber intValue])

Zamieni się w to:
([array count] == 0)
([someNumber intValue])

Mam nadzieję że to pomoże.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Praca ze Swift 2.0 i parsowanie:
var myNumber = yourArray!.objectForKey("yourColumnTitle")
if (myNumber == nil) {
myNumber = 0
}

W moim przypadku musiałem wtedy:
let myNumberIntValue = myNumber!.intValue
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

NSNumber
są niezmienne i mogą być tworzone tylko przy użyciu metody Factory lub metody początkowej, która nadaje im pewną wartość liczbową. O ile wiem, nie można uzyskać „pustego” numeru NS, chyba że policzysz 0.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Bardzo często (przynajmniej dla mnie) obiekt jest pobierany ze słownika, oczekując, że będzie to numer NS, a następnie zwraca obiekt pusty. Jeśli tak się stanie i zrobisz intValue, nastąpi awaria.
To, co robię, czy mogę zainstalować zerową ochronę, ponieważ wolałbym uzyskać wartość domyślną niż awaria.
Jednym ze sposobów jest:
-(int) intForDictionary:(NSDictionary *)thisDict objectForKey: (NSString *)thisKey withDefault: (int)defaultValue
{
NSNumber *thisNumber = [thisDict objectForKey:thisKey];
if (thisNumber == nil) {
return defaultValue;
}
return [thisNumber intValue];
}

I mam dokładnie taki sam dla pływaków. Wtedy przynajmniej otrzymasz domyślne. Innym sposobem jest po prostu utworzenie zerowej metody ochrony.
-(NSNumber *)nilProtectionForNumber: (NSNumber *)thisNumber withDefault: (NSNumber *)defaultNumber
{
if (thisNumber) {
return thisNumber;
}
else
return defaultNumber;
}

Ten, którego nazwałbyś tak:
NSNumber *value = [self nilProtectionForNumber:[dict objectForKey:keyThatShouldBeNSNumber] withDefault:[NSNumber numberWithInt:0]];

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się