2010-09-20 16 views
17

Uwielbiam skróconą obsługę literałów ciągów w Objective C z notacją @"string". Czy istnieje sposób na uzyskanie podobnego zachowania z NSNumber s? Mam do czynienia z liczbami więcej i to jest tak nużące, mając wszędzie połączenia [NSNumber numberWithWhatever:]. Nawet tworzenie makra zadziałałoby, ale moja wiedza na temat tego, jak najlepiej to zrobić, jest ograniczona.@ "" Literały typu ciągów dla NSNumber

+0

Jak wskazano przez rjstelling, jest to teraz funkcja w klang. Wiele radości. Głosuj, aby zamknąć, dzięki. – rob5408

+0

Nie trzeba tego zamykać. To doskonale poprawne pytanie. Zamknięcie dotyczy niepożądanych pytań, w których należy zapobiegać odpowiedziom. –

+1

Zamiast tego należy przyjąć odpowiedź @ rjstelling, ponieważ jest teraz bardziej poprawna. –

Odpowiedz

11

Używam makra jak

#define N(x) [NSNumber numberWithInt: x] 

wich prowadzi do kodu jak

[N(123) intValue]; 

zmiana:

Trzeba zdawać sobie sprawę z procesora i pamięci konsumpcji takich makro. Podczas gdy ciągi znaków @"…" są kompilowane przez ciągi ciągłej klasy ciągów (w zależności od fundacji może być NSConstantString w kakao?), Makra tworzą kod, który jest oceniany w czasie wykonywania, a zatem tworzy nowy obiekt za każdym razem, gdy są wywoływane.

+0

Niezły, to zadziała. Dzięki! – rob5408

+3

Nieznaczne ulepszenie: '#define N (x) [NSDecimalNumber decimalNumberWithString: @" "#x]".Pozwoli ci to na robienie rzeczy takich jak 'N (1.4)' lub 'N (1E09)' – JeremyP

+1

Tak, ale czy to nie jest znaczące wolniejsze? Używam makro 'F (x)' dla punktów zmiennoprzecinkowych, które wywołują '[NSNumber numberWithDouble: x]'. –

30

Od Clang v3.1 można teraz używać literałów C dla celów.

NSNumber *fortyTwo = @42;    // equivalent to [NSNumber numberWithInt:42] 
NSNumber *fortyTwoUnsigned = @42U; // equivalent to [NSNumber numberWithUnsignedInt:42U] 
NSNumber *fortyTwoLong = @42L;  // equivalent to [NSNumber numberWithLong:42L] 
NSNumber *fortyTwoLongLong = @42LL; // equivalent to [NSNumber numberWithLongLong:42LL] 

Więc odpowiadając na konkretne pytanie:

[Tyler setArms:[[[NSNumber alloc] initWithInt:1] autorelease]]; 

mogą być zapisane jako:

[Tyler setArms:@1]; 

Istnieją również literały dla tablic i słowników, ale są one poza zakresem to pytanie.

Aby skorzystać z literałów w Xcode, potrzebujesz przynajmniej wersji 4.4 - jest ona dostarczana z kompilatorem LLVM 4.0 firmy Apple.

+2

Tak, bardzo ekscytujące! Poza tym zamierzam zamknąć to pytanie, zanim milion ludzi powie mi, że jestem idiotą. – rob5408

+2

@ rob5408 nikt nie będzie myślał o twoim idiocie, jest to ważne pytanie i pytałeś o to prawie 2 lata przed tym, jak był dostępny. Otrzymujesz ode mnie +1. – Joe

+0

Nie ma odpowiedniego skrótu dla zmiennej typu NSInteger, float, double, więc na? –

7

Xcode 4.4 wprowadził funkcje Clang, które rjstelling mentioned dla literałów dla NSNumber, NSArray i NSDictionary. Składnia jest prosta:

//Number literal 
NSNumber *pi = @3.14; 

//Array literal 
NSArray *primes = @[ @2, @3, @5, @7, @11 ]; //No nil terminator needed 

//Dictionary literal 
NSDictionary *dict = @{ 
    @"key1": @42, 
    @"key2": @"Another key", 
    @3: @"A NSNumber key" 
}; //No nil terminator, stored in "key:value," format 
28

Ponieważ nikt nie wspomniał o tym ... Jeśli trzeba owinąć wartość w NSNumber, składnia dosłowne NSNumber jest następujący.

int val = 13; 
NSNumber *numVal = @(val); 
+0

Cześć Adam, dobry punkt. Nawet po pojawieniu się nowej składni nie było to dla mnie oczywiste. – rob5408

+1

Czy istnieje skrót na odwrót? Sposób na usunięcie intValue z NSNumber? – Rob

+0

dokładnie to, czego szukałem! – DonnaLea