2009-07-21 16 views

Odpowiedz

708

@synthesize wygeneruje metody getter i setter dla twojej własności. @dynamic mówi kompilatorowi, że metody pobierające i ustawiające są zaimplementowane nie przez samą klasę, ale gdzieś indziej (np. Nadklasy lub zostaną dostarczone w czasie wykonywania).

Zastosowania dla @dynamic to np. z podklasami NSManagedObject (CoreData) lub gdy chcesz utworzyć wylot dla właściwości zdefiniowanej przez nadklasę, która nie została zdefiniowana jako wylot.

@dynamic może również służyć do delegowania odpowiedzialności za wdrożenie akcesorów. Jeśli implementujesz akcesorów w klasie, zwykle nie używasz @dynamic.

Super klasa:

@property (nonatomic, retain) NSButton *someButton; 
... 
@synthesize someButton; 

Podklasa:

@property (nonatomic, retain) IBOutlet NSButton *someButton; 
... 
@dynamic someButton; 
+23

nie jest w 100% prawidłowe; dynamic jest wartością domyślną, jeśli nie ustawisz opcji @synthesize lub @dynamic. Określenie @dynamic oznacza jedynie, że bierzesz odpowiedzialność za prawidłowe wdrożenie obiektów dostępowych do właściwości na podstawie podpisu deklaracji własności. – Kevlar

+67

Niezupełnie, @dynamic oznacza, że ​​odpowiedzialność za wdrożenie akcesorów jest delegowana. Jeśli implementujesz akcesorów w klasie, zwykle nie używasz @dynamic. – diederikh

+2

Otrzymałem błędy 'NSUnknownKeyException' z moją właściwością dynamiczną, gdy usunąłem linię' @ synthesize' (Xcode 3.2 dało mi błąd b/c Nie miałem pasującego ivar dla mojego @property). Dodanie '@ dynamic' rozwiązało problem - teraz kompiluje i działa dobrze. Dzięki! – pix0r

206

Spójrz na this article; pod nagłówkiem "Metody dostarczane w czasie wykonywania":

Niektóre obiekty dodawane są tworzone dynamicznie w czasie wykonywania, na przykład niektóre używane w klasie NSManagedObject programu CoreData. Jeśli chcesz zadeklarować i użyć właściwości dla tych przypadków, ale chcesz uniknąć ostrzeżeń o metodach, których brakuje w czasie kompilacji, możesz użyć dyrektywy @dynamic zamiast @synthesize.

...

Używanie @dynamic dyrektywa zasadniczo informuje kompilator „nie martw się o tym, gdy metoda nie jest po drodze.”

Dyrektywa @synthesize, z drugiej strony, generuje metody dostępowe dla Ciebie w czasie kompilacji (chociaż jak zauważono w „Mieszanie syntetyzowane i niestandardowych dostępowych” sekcji jest elastyczny i nie generuje metody, czy też są zaimplementowane).

+25

To Morer-correcter człowiekiem. Ta odpowiedź jest jedyną odpowiedzią, która mówi o metodach tworzonych w czasie wykonywania, które naprawdę zdają się wychwytywać ducha o wiele bardziej niż najlepsze głosowanie – bobobobo

+1

Wszyscy powinni upvote this. –

+0

@AnkitSrivastava robi "dynamiczny" również ivar? – onmyway133

29

Jak mówili inni, w ogóle użyć @synthesize mieć kompilator generowania pobierające i/lub ustawienia dla ciebie, i @ dynamiczne, jeśli masz zamiar napisać je samemu.

Istnieje jeszcze jedna subtelność, o której jeszcze nie wspomniano: @synthesize będzie pozwala na samodzielną implementację programu typu getter lub setera. Jest to użyteczne, jeśli chcesz tylko zaimplementować getter dla jakiejś dodatkowej logiki, ale pozwól kompilatorowi wygenerować setter (który dla obiektów jest zwykle nieco bardziej skomplikowany do napisania).

Jednakże, jeśli napiszesz implementację akcesora @ synthesize, musi on nadal być wspierany przez prawdziwe pole (np. Jeśli napiszesz -(int) getFoo();, musisz mieć pole int foo;). Jeśli wartość jest wytwarzana przez coś innego (np. Obliczona z innych pól), musisz użyć @dynamic.

+2

+1, aby wspomnieć o ważnej różnicy: @dynamic pozwala tworzyć akcesoria dla zmiennych, które nie są zdefiniowane w interfejsie klasy i poprzez introspekcję. – mahboudz

+24

"i' @ dynamic', jeśli masz zamiar napisać je samemu "Nie, NIE używasz dynamicznego, jeśli sam je napiszesz. '@ dynamic' wyłącza sprawdzanie kompilatora, aby upewnić się, że zostały zaimplementowane. Jeśli zostały one zaimplementowane samodzielnie, chcesz, aby kompilator sprawdził. – user102008

14

@dynamic jest zwykle używany (jak wspomniano powyżej), gdy właściwość jest tworzona dynamicznie w czasie wykonywania. NSManagedObject robi to (dlaczego wszystkie jego właściwości są dynamiczne) - co tłumi ostrzeżenia kompilatora.

Na dobry przegląd na temat tworzenia właściwości dynamicznie (bez NSManagedObject i CoreData :, patrz: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#//apple_ref/doc/uid/TP40008048-CH102-SW1

6

Jedno chcę dodać, że jeżeli nieruchomość została zadeklarowana jako @dynamic nie będzie zajmować pamięć (I . potwierdzona instrumentu alokacji) konsekwencją jest to, że można zadeklarować właściwości w kategorii klasy

+0

Jeśli przesłonię funkcję ustawiania właściwości w kategorii i sprawię, że będzie dynamiczna, czy to zagwarantuje, że przesłonięcie zostanie użyte w czasie wykonywania, a nie w ustawieniu klasy nadrzędnej? Z dokumentów firmy Apple: "Jeśli nazwa metody zadeklarowanej w kategorii jest taka sama jak metoda w oryginalnej klasie ... zachowanie nie jest zdefiniowane, która implementacja metody jest używana w środowisku wykonawczym." –

+0

Nie, myślę, że zachowanie jest wciąż niezdefiniowane. Utworzenie właściwości w kategorii dynamicznej nie zmienia priorytetu środowiska wykonawczego metody ustawiającej właściwości. –

13

here is przykładem @dynamic

#import <Foundation/Foundation.h> 

@interface Book : NSObject 
{ 
    NSMutableDictionary *data; 
} 
@property (retain) NSString *title; 
@property (retain) NSString *author; 
@end 

@implementation Book 
@dynamic title, author; 

- (id)init 
{ 
    if ((self = [super init])) { 
     data = [[NSMutableDictionary alloc] init]; 
     [data setObject:@"Tom Sawyer" forKey:@"title"]; 
     [data setObject:@"Mark Twain" forKey:@"author"]; 
    } 
    return self; 
} 

- (void)dealloc 
{ 
    [data release]; 
    [super dealloc]; 
} 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector 
{ 
    NSString *sel = NSStringFromSelector(selector); 
    if ([sel rangeOfString:@"set"].location == 0) { 
     return [NSMethodSignature signatureWithObjCTypes:"[email protected]:@"]; 
    } else { 
     return [NSMethodSignature signatureWithObjCTypes:"@@:"]; 
    } 
} 

- (void)forwardInvocation:(NSInvocation *)invocation 
{ 
    NSString *key = NSStringFromSelector([invocation selector]); 
    if ([key rangeOfString:@"set"].location == 0) { 
     key = [[key substringWithRange:NSMakeRange(3, [key length]-4)] lowercaseString]; 
     NSString *obj; 
     [invocation getArgument:&obj atIndex:2]; 
     [data setObject:obj forKey:key]; 
    } else { 
     NSString *obj = [data objectForKey:key]; 
     [invocation setReturnValue:&obj]; 
    } 
} 

@end 

int main(int argc, char **argv) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    Book *book = [[Book alloc] init]; 
    printf("%s is written by %s\n", [book.title UTF8String], [book.author UTF8String]); 
    book.title = @"1984"; 
    book.author = @"George Orwell"; 
    printf("%s is written by %s\n", [book.title UTF8String], [book.author UTF8String]); 

    [book release]; 
    [pool release]; 
    return 0; 
} 
9

zgodnie z dokumentacją.

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html

@dynamic informuje kompilator, że metody dostępowe są zaopatrzone w czasie wykonywania.

Po drobiazgowym sprawdzeniu dowiedziałem się, że udostępnienie metod zastępuje dyrektywę @ dynamic.

@synthesize informuje kompilator do tworzenia tych akcesorów dla Ciebie (getter i setter)

@property informuje kompilator, który zostanie utworzony akcesory, i które mogą być dostępne z notacją kropka lub [wiadomość obiektu]

0

Zgodnie z dokumentacją Apple.

użyć oświadczenie @synthesize w bloku implementacji klasy, aby poinformować kompilator, tworzyć implementacje, które odpowiadają specyfikacji dałeś w deklaracji @property.

Należy użyć instrukcji @dynamic, aby nakazać kompilatorowi pominięcie ostrzeżenia, jeśli nie może znaleźć implementacji metod akcesorów określonych w deklaracji @property.

Więcej informacji: -

https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/DeclaredProperty.html

Powiązane problemy