2009-08-16 11 views

Odpowiedz

50

Istniejące odpowiedzi są przydatne; dodając do nich:

Tak, NSUInteger daje dwukrotnie większy zasięg wśród liczb całkowitych dodatnich jak NSInteger, ale myślę, że kolejnym ważnym powodem, aby wybrać między nimi jest po prostu rozróżnić przypadkach ujemne wartości po prostu nie ma sensu.

przykład: wartość powrotu count metodą NSArray jest to NSUInteger, co ma sens, ponieważ nie może mieć tablicę z ujemną liczbą elementów. Kiedy programista wie, że jest niepodpisany, ma większą swobodę wykonywania operacji, które mogą być niewiarygodne w podpisanym przypadku, w tym operacje bitowe, takie jak zmiana. This blog post mówi więcej o podpisie kontra niepodpisanym.

Domyślam o CGFloat vs NSFloat (który nie istnieje): To może być tak, że projektanci NeXTStep-nazwanych elementów kodu po prostu nie trzeba określać zbyt wiele wartości float, poza czasem interwały. Podali więc NSTimeInterval, który jest typem zmiennoprzecinkowym, ale jest to wyraźnie przeznaczone do użycia z przedziałami czasowymi. Szczerze mówiąc, wspaniale jest mieć ten typ, ponieważ wiesz, że zawsze ma być w sekundach bez konieczności zajmowania się strukturą. Kiedy wkraczasz w świat grafiki (gdzie żyje Core Graphics), nagle pływają wokół Ciebie, unosi się w powietrzu (haha). Dlatego warto wprowadzić tam CGFloat. Ten akapit to "wykształcona spekulacja".

również, żeby mieć jasność co czemu można użyć NSInteger etc zamiast prymitywnych typów: Ponieważ w ten sposób łatwiej jest pisać przenośny kod, który w pełni wykorzystuje architekturę maszyny. Na przykład, CGFloat wykorzystuje 32 bity na niektórych maszynach i 64 bity na innych, w dużej mierze zależnie od tego, ile luki wydajności istnieje na tych maszynach dla tych rozmiarów. W niektórych przypadkach nie ma prawdziwego przyspieszenia dla korzystania z 32 bitów w porównaniu do 64 bitów, więc równie dobrze możesz użyć 64 bitów. Jeśli zadeklarowałeś rzeczy jako CGFloat, nagle uzyskasz tę dodatkową precyzję "za darmo", kiedy dokonujesz rekompilacji.

I jak iKenndac wskazał, NSNumber jest klasa wrapper dla wszystkich z tych (i innych prymitywnych lub quasi-prymitywne typy takie jak BOOL), co pozwala umieścić go w swoim NSArray s oraz NSDictionary s, zarchiwizuj je łatwiej i wykonaj inne czynności, które może wykonać użytkownik.

+0

Naprawdę, naprawdę niedelikatny punkt: NSTimeinterval jest podwójnym, a nie float. Mam świadomość, że double jest skrótem dla zmiennoprzecinkowego podwójnej precyzji, ale nadal. Rozumiem też, że kompilacja CGFloat jako double na 64-bit jest świetna, ale NSInteger? Nie mogę wymyślić sytuacji, w której byłoby to użyteczne. Powiedzmy w kodzie, że robisz matematykę, która wymaga 64 bitów ... nie możesz użyć NSIntegera, jeśli kompilujesz dla 32. Jeśli pasujesz do 32, dlaczego używasz 64? Wydaje się dziwne. – iKenndac

+1

Masz rację, NSTimeInterval jest podwójne. Myślę, że nadal liczy się jako "zmiennoprzecinkowy". Z podwójną precyzją. Zgadzam się również, że w wielu przypadkach wiele kodu nie ulegnie poprawie, ponieważ NSInteger stanie się 64-bitowym. Ale jest jedna możliwość: generator liczb losowych. W tym przypadku naprawdę zależy Ci na prędkości, więc możesz chcieć użyć 32 bitów, gdy jest to szybsze. Ale jeśli 64 bity działają równie dobrze, wtedy nagle dostaniesz ogromny impuls szczęścia losowego (_much_ dłuższa długość cyklu, itp.) Bez dużego (jeśli w ogóle) kosztu prędkości. – Tyler

+0

Dlaczego możemy zagłosować raz? Znakomity! –

56

NSNumber to klasa, a nie prymitywna, i jest używana, gdy trzeba umieścić surowe liczby w słownikach, tablicach lub w inny sposób je enkapsulować. NSInteger, NSUInteger, itp. Są prostymi typami i odpowiadają (w systemach 32-bitowych, takich jak iPhone) na int, unsigned int i float.

Zgodnie z ogólną zasadą, jeśli musisz gdzieś przechowywać numer, użyj NSNumber. Jeśli robisz obliczenia, pętle itp., Użyj NSInteger, NSUInteger lub .

możesz otoczyć NSInteger w produkt NSNumber:

NSNumber *aNumber = [NSNumber numberWithInteger:21]; 

... i dostać go z powrotem:

NSInteger anInteger = [aNumber integerValue]; 

Możesz dowiedzieć się więcej informacji tutaj: http://iosdevelopertips.com/cocoa/nsnumber-and-nsinteger.html

+0

Jeśli liczba nigdy nie będzie ujemna, czy powinienem używać NSUInteger? – mk12

+0

A co mam użyć dla liczby z dziesiętną? – mk12

+0

Dlaczego to jest CGFloat, a nie NSFloat? – mk12

5

NSInteger jest tak jak tradycyjny int w C. To jest typedef. Istnieją inne, takie jak NSUInteger, CGFloat itd., Że wszystkie są synonimami dla typów pierwotnych.

NSNumber jest przydatny, gdy trzeba wprowadzić numer do NSArray lub NSDictionary. Standardowa praktyka polega na używaniu tych kolekcji w porównaniu do toczenia własnych; wadą jest to, że mogą zawierać tylko obiekty Objective-C.

NSNumber zasadniczo otacza się int (lub pływaka, etc.) do obiektu obj-C (podobne do pojęcia C#/Javy, „boksu” pierwotny typu), które mogą być dodawane do tablicy:

NSArray * myArray = [[NSArray alloc] init]; 
[myArray addObject:3]; // invalid, will not compile. 
[myArray [NSNumber numberWithInt:3]]; // ok 

Ze względów wydajnościowych, jeśli możesz, użyj typów pierwotnych (takich jak int, float, int []). Czasami jednak nie można uniknąć NSArray/NSNumber, na przykład podczas czytania lub zapisywania wpisów w pliku .plist.

+1

NSInteger, NSUInteger i CGFloat są typedefs, które są bezpieczne w wersji 32 lub 64-bitowej. – Abizern

0

Jak powiedzieli inni przed, NSNumber jest podklasa NSObject. To nie jest prymityw C (jak int, unsigned int, float, double, itp.) NSInteger, CGFloat, NSUInteger są proste typedefs nad prymitykami C.

Zapotrzebowanie na NSNumber wynika z potrzeby użycia liczb jako parametrów do API, które wymagają obiektów. Przykład: kiedy chcesz zapisać numer w NSArray, w Core-Data lub w NSDictionary.

Czy jest więcej takich prymitywów, o których powinienem wiedzieć? No cóż, NSNumber nie jest typem pierwotnym i owija się wokół różnego rodzaju liczb (zmiennoprzecinkowe, całkowe, booleans i tak dalej). Powinieneś także dowiedzieć się o NSValue, która jest bazą dla NSNumber.

Czy jest jeden do pływaków? Nie ma „NS” typedef dla pływaka, ale NSNumber można owinąć wokół dowolnej liczby float:

NSNumber *myPi = [NSNumber numberWithFloat:3.1415926]; 

Albo można użyć CoreGraphics prymitywny typ CGFloat.

2

NSNumber jest zazwyczaj używany do przechowywania zmiennych NSUInteger służy do arytmetyki

można zmienić NSNumber do NSUInteger w ten sposób:

NSNumber *variable = @1; 
NSUInteger variableInt = [variable unsignedIntegerValue]; 

To zostało powiedziane wcześniej, ale co do zasady of kciuka, zmiennymi, które muszą być zdefiniowane za pomocą * są klasy C, podczas gdy zmiennymi, które nie potrzebują *, są prymitywy C.

Powiązane problemy