2008-11-08 8 views
22

Jedną z cech współczesnego (64-bitowego OS X OS X i iPhone OS) środowiska wykonawczego Objective C jest zdolność do dynamicznej syntezy znaków ivar bez wyraźnego deklarowania ich w klasa:Jaki jest podstawowy mechanizm syntezy ivar w nowoczesnym środowisku wykonawczym Objective C

@interface MyClass : NSObject { 
// NSString *name; unnecessary on modern runtimes 
} 

@property (retain) NSStrng *name; 

@end 

@implementation MyClass 

@synthesize name; 

@end 

w zupełnie kawałka mojego kodu używam niestandardowe implementacje getter aby zainicjować właściwości:

- (NSString *) name { 
    if (!name) { 
    name = @"Louis"; 
    } 

    return name; 
} 

powyższe jest niezgodne z syntetyzowanych Ivars ponieważ potrzebuje dostępu tematyce ivar to nie jest deklaracja ed w nagłówku. Z różnych powodów chciałbym zaktualizować wiele moich osobistych frameworków, aby używać zsyntetyzowanych ivars, gdy są zbudowane na nowoczesnych środowiskach wykonawczych, powyższy kod musi zostać zmodyfikowany, aby działał z syntezowanymi ivars, aby osiągnąć ten cel.

Podczas gdy dokumentacja Celu C 2.0 stwierdza, że ​​syntezowane dodatki w nowoczesnym środowisku wykonawczym zsyntetyzują ivar przy pierwszym użyciu. Nie określa, do czego służy ten mechanizm niskiego poziomu. Czy jest to zrobione przez class_getInstanceVariable(), czy ograniczenia dotyczące class_addIvar() są rozluźnione, czy jest to funkcja nieudokumentowana w obiektywnym środowisku wykonawczym C 2.0? Chociaż mogłem zaimplementować własne składowanie po stronie dla danych wspierających moje właściwości, wolałbym raczej użyć mechanizmu, którego używają syntezowane akcesory.

+1

Byłbym naprawdę pod wrażeniem, jeśli masz odpowiedź na to – Shawn

Odpowiedz

21

Poszedłem i ponownie przejrzałem dokumentację, i myślę, że źle to rozumiesz. Zsyntetyzowane znaki iv są tworzone podczas kompilacji, a nie w czasie wykonywania.

Według Objective-C 2.0 documentation:

istnieją różnice w zachowaniu, które są uzależnione od wykonywania (patrz także „Różnice wykonania”):

za czasy pracy starszych, zmienne instancji muszą już być uznana w bloku @interface. Jeśli istnieje instancja o tej samej nazwie i zgodnym typie, jak ta właściwość, jest ona używana - w przeciwnym razie wystąpi błąd kompilatora.

W przypadku współczesnych środowisk wykonawczych w razie potrzeby syntetyzowane są zmienne instancji. Jeśli zmienna instancji o tej samej nazwie już istnieje, jest używana.

Więc wszystko co musisz zrobić, to zadeklarować zmienną instancji trzeba, a sam kod będzie działać na obu czasy pracy ...

+2

Po przeczytaniu kodu syntezatora GCC to w rzeczywistości to, co jest dziać się. –

+1

Jednym z ulepszeń w kompilatorach ery Xcode 3.2 (Clang/LLVM i GCC 4.2) jest to, że można uzyskać ivars tych, które są tworzone w celu wspierania syntezowanych zmiennych, nawet jeśli nie są one zadeklarowane w klasie, co czyni to wszystko nieco dyskusyjną . –

-6

dodać właściwości w czasie wykonywania z NSKeyValueCoding Protocol.

[myObject setValue:@"whatever" forKey:@"foo"]; 
+2

To nieprawda. Można * ustawiać * wartości za pomocą kodowania klucz-wartość, ale nie można w ten sposób dodawać właściwości. – jlehr

+0

Absolutnie można dodawać nowe wartości za pomocą NSKeyValueCoding, jeśli klasa implementuje ten protokół. Ale masz rację, że jest to zła odpowiedź na to pytanie, ponieważ ivars są tworzone podczas kompilacji, a nie z NSKeyValueCoding. – jazzdev

+1

Ponownie przeczytaj odpowiedź. Nie można dodać * właściwości * za pomocą kodowania klucz-wartość. – jlehr

0

Co szukasz jest @synthesized nazwy, jak:

@synthesize name = _name; 

... 

- (NSString *) name { 
    if (!name) { 
     _name = @"Louis"; 
    } 

    return _name; 
}