2011-07-22 3 views
47

oglądałem wprowadzenie wideo WWDC ARC i zobaczyłem coś, czego nigdy nie widziałem w ObjC wcześniej, kiedy jakiś inżynier Jabłko mówił o przykład stosu.Zmienne instancji zadeklarowane w objc pliku wdrażania

Poniższy kod został wykorzystany na przykład stosu z łuku:

@implementation Stack 
{ 
    // instance variable declared in implementation context 
    NSMutableArray *_array; 
} 

- (id)init 
{ 
    if (self = [super init]) 
     _array = [NSMutableArray array]; 
    return self; 
} 

- (void)push:(id)x 
{ 
    [_array addObject:x]; 
} 

- (id)pop 
{ 
    id x = [_array lastObject]; 
    [_array removeLastObject]; 
    return x; 
} 

@end 

Uwaga zmiennej instancji zadeklarowaną tuż po dyrektywie @implementation.

Teraz zaskoczyło mnie to, że zmienna instancji może zostać zadeklarowana w pliku implementacyjnym, nie będąc zmienną statyczną. Moje pytania byłyby następujące:

  • Czy jest to nowa konstrukcja wprowadzona w pakiecie SDK dla systemu iOS 5, czy jest to możliwe przez długi czas?
  • Czy dobrze byłoby zadeklarować zmienne instancji w implementacji, jeśli zmienne instancji nie będą dostępne poza obiektem? Wydaje się, że jest to o wiele czystsze niż użycie dyrektywy @private.
+0

Czy masz pełny, nadający się do kompilacji przykład tego? –

+0

Powyższy kod powinien się dobrze skompliować z zestawem SDK iOS 5. –

+0

Co powiesz na dodanie iVars do rozszerzenia klasy? –

Odpowiedz

39

Jest to rzeczywiście nowa cecha języka, a jeśli musisz zadeklarować swoje ivars (zamiast po prostu deklarować właściwości i pozwolić kompilatorowi generować ivars dla ciebie) to dobra praktyka. Twoje pliki nagłówkowe teoretycznie powinny tylko eksponować publiczny interfejs dla twoich zajęć; wszystko inne należy do implementacji.

Jednym z zastrzeżeń jest to, że ivars plików implementacji nie są widoczne dla podklas, co może czasami być trochę niezręczne, jeśli ręcznie wygenerowano zmienne i pobierające, które należy poddać podklasie.

+1

Powiedzmy, że stworzyłem klasę "A", która deklaruje tylko ivars w pliku implementacji (do enkapsulacji), ale chcę utworzyć zmienną podmenu "MutableA". Jak mogę uzyskać dostęp do ivars implementacji w A? Uwaga: nie ma właściwości ani modułów pobierających/ustawiających dla tych znaków iv. – Grimless

+1

Inżynier Apple powiedział mi o nowej funkcji i zalecił jej użycie. Trochę o tym zapomniałem, dopóki nie spojrzałem na NSAttribututedString.h i nie mogłem znaleźć ivars. Temat Objective-C „Definiowanie klasy” zostało odpowiednio zaktualizowane, a odnosi się do deklaracji Ivars w interfejsie jako „historyczne” Jeśli chodzi o widoczność w podklasach - implementacje zrobić Podklasa wystarczy użyć funkcji dostępowe? – GTAE86

+1

@ GTAE86 Tak, chociaż myślę, że nadal dość często używam deklaracji nagłówków (lub kombinacji deklaracji nagłówka i implementacji). –

17

Deklaracja iVars w implementacji jest z pewnością nową konstrukcją w ramach celu C. Musisz używać xcode4.2 i mieć kompilator LLVM wybrany w ustawieniach kompilacji. Chodzi o to, aby pliki nagłówkowe były czystsze. Możesz wymienić swoje ivars wewnątrz nawiasów klamrowych jak w tym przykładzie;

@implementation MyClass {  
    int var1; 
    int var2; 
} 

Odpowiedź udzielona przez Rahul nie jest do końca poprawne, choć można delare zmiennych w sposób mówi on byłyby postrzegany jako statyczny przez kompilator. Prawdopodobnie dla przypadków, w których ich użył, nie miało to znaczenia.

+1

Należy również kwalifikować się do środowiska "Modern" Objective-C, które zgodnie z https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtVersionsPlatforms.html jest dostępne w systemie iOS oraz OS X 10.5 i nowszych 64-bitowych. OS X w wersjach starszych niż 10.5 i 32-bitowych w systemie OS X używa starszego środowiska wykonawczego. – bleater

4

Jestem nowy Objective C i znalazłem praktykę deklarując Ivars w nagłówku bardzo dziwne. Oznacza to deklarowanie wewnętrznego stanu obiektu w jego publicznym nagłówku, co jest sprzeczne z koncepcją enkapsulacji.

Załóżmy na przykład, że masz iPada. Apple nie chce, abyś otworzył i otworzył iPada i bałagan z żywiołami w środku. Jeśli chcą, abyś coś zmodyfikował, IPad będzie miał ustawienie, które pozwoli ci to zmienić.

Podobnie, nie chcę, aby inni programiści widzieli ivar obiektów. Jest to stan wewnętrzny mojego obiektu. Jeśli chcę, abyś uzyskał stan wewnętrzny, zadeklaruję właściwości dla niego.

Tak, jak w innych languaes, chciałbym ukryć moje Ivars wewnątrz implementationfile, a nie je zadeklarować w nagłówku.

Deklarowanie Ivars w nagłówku po prostu wydaje mi się bardzo dziwne. Te ivars są specyficzne dla implementacji i powinny po prostu nie być częścią pliku nagłówkowego.