2009-05-27 11 views
9

Jestem nowy w Objective-C i kakao. Czytałem, że NSInteger i NSNumber są preferowane podczas pracy z prostymi liczbami całkowitymi, ponieważ są "bezpiecznymi dla platformy" wersjami podstawowych typów liczbowych (oraz w przypadku NSNumber zawiniętymi w obiekt). Potrzebuję więc licznika w mojej klasie, który zwiększa się, gdy uruchamia się NSTimer. Na forum Apple znalazłem grupę ludzi, która wszystkim polecała komuś w podobnej sytuacji, że powinni zadeklarować wskaźnik NSNumber w nagłówku, zainicjować go za pomocą numberWithInt :, a następnie za każdym razem, gdy musi zostać zwiększony, zrób to przez przypisanie go do nowy obiekt (coś w stylu: counter = [NSNumber numberWithInt:[counter intValue]+1];). Dla mnie to wygląda na przesadę. Jeśli wszystko, czego potrzebuję, to licznik int (i przy okazji resetuję go z powrotem do 0, po trafieniu 15, więc rozmiar nie jest problemem), nie mogę uciec z użyciem tylko int i nie trzeba przydzielać nowy obiekt z każdą iteracją pętli mojego timera?Czy liczba przeskoków NSNumber dla licznika na poziomie instancji?

A jeśli tak, w jaki sposób udostępnić typ pierwotny w mojej klasie. Wiem, że z typami obiektów deklaruję to w moim interfejsie i używam @property i @synthesize ... jaki jest ekwiwalent (jeśli taki istnieje) podczas pracy z prymitywami?

+0

Do twojego drugiego pytania: To jest to samo, po prostu użyj @property i @synthesize. –

Odpowiedz

15

Używanie NSNumber do prostego licznika wygląda trochę na zabicie. Można zadeklarować członków klasy jako NSInteger i po prostu je zaktualizować za pomocą ++ lub + =

na przykład:

@interface YourViewController : UIViewController { 
NSInteger counter;  
} 

@property (nonatomic,assign) NSInteger counter; 

@synthesize jest po prostu:

@synthesize counter 

i może być zwiększany poprzez :

self.counter += 1; 

lub

późniejsze zapobiegnie informowaniu obserwatorów, dlatego może nie być korzystne.

+0

Nie wiedziałem, że + = pracował na nieruchomościach ... dzięki @gs –

9

NSNumber to obiekt reprezentujący liczbę. Używam go podczas przechowywania liczb w klasie kolekcji, ponieważ mogą one jedynie zawierać wskaźniki obiektów.

Tak więc w twoim przykładzie, który wymaga licznika, prawdopodobnie jest to przesada.

NSInteger to po prostu liczba całkowita, która jest bezpieczna dla programów 32- i 64-bitowych i jest zalecana przez firmę Apple do użytku zamiast int. To nie jest przedmiot. Jest to prawdopodobnie potrzebne do licznika (w rzeczywistości NSUInteger, który jest unsigned int) może być lepszy.

Co do tworzenia prymitywów dostępnych w całej klasie - cóż, jeśli zadeklarujesz ją w nagłówku jako iVar, to i tak będzie ona dostępna w całej klasie. @property i @synthesize to po prostu Objective-C 2.0 sposoby deklarowania ich jako właściwości, które można zobaczyć (i być może zmienić) poza klasą w sposób zgodny z KVC/KVO. Typy pierwotne mogą być używane jako właściwości przy użyciu tej samej składni @property i @synthesize.

4

używam NSInteger (nie int, aby być bardziej przenośne) i owinąć go w NSNumber jeśli trzeba dodać ją do kolekcji (takich jak NSMutableDictionary podczas zapisywania stanu na wyjściu z aplikacji).

1

Zgadzam się z twoim instynktem, użycie obiektu dla prostego licznika brzmi jak przesada i doda niepotrzebną liczbę wywołań wiadomości dla po prostu zwiększenia licznika. Dla licznika, który nie musi być przechowywany w zbiorze lub manipulowany jako obiekt, należy trzymać się typów skalarnych C.

Aby zadeklarować skalarne jako zmiennej instancji swojej klasie, po prostu zadeklarować je w pliku nagłówka:

@interface MyClass: NSObject{ 
    int counter; 
} 

@end 
0

Jeśli zrobić potrzebę, aby zwiększyć się NSNumber (takie jak dla własności NSManagedObject) I znaleziono kategoria ta pomogła:

@interface NSNumber (Incrementer) 
- (NSNumber *)increment; 
@end 

@implementation NSNumber (Incrementer) 
- (NSNumber *)increment { 
    return [NSNumber numberWithInt:[self intValue]+1]; 
} 
@end 

więc można uprościć sprawozdań inkrementalnej:

counter = [counter increment];