Odpowiedzi:
@synthesize wygeneruje metody pobierające i ustawiające dla Twojej właściwości. @dynamic po prostu mówi kompilatorowi, że metody pobierające i ustawiające są implementowane nie przez samą klasę, ale gdzie indziej (np. nadklasę lub zostaną udostępnione w czasie wykonywania).
Zastosowania @dynamic są np. Z podklasami NSManagedObject
(CoreData) lub gdy chcesz utworzyć ujście dla właściwości zdefiniowanej przez nadklasę, która nie została zdefiniowana jako ujście.
@dynamic można również wykorzystać do przekazania odpowiedzialności za implementację akcesoriów. Jeśli implementujesz akcesoria samodzielnie 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;
NSUnknownKeyException
Podczas usuwania @synthesize
linii pojawiały się błędy w mojej właściwości dynamicznej (Xcode 3.2 dawał mi błąd b / c, że nie miałem pasującego ivar dla mojej @property). Dodanie @dynamic
naprawiło problem - teraz kompiluje się i działa poprawnie. Dzięki!
@property
przedmioty, które nie mają ani @synthesize
nie @dynamic
będą automatycznie syntezowane. Dla każdej właściwości zostanie utworzony ivar z wiodącym podkreśleniem, np. _propertyName
Wraz z odpowiednim narzędziem pobierającym i ustawiającym.
Spójrz na ten artykuł ; w tytule „Metody udostępniane w czasie wykonywania”:
Niektóre akcesoria są tworzone dynamicznie w czasie wykonywania, takie jak niektóre używane w klasie NSManagedObject CoreData. Jeśli chcesz zadeklarować i użyć właściwości dla tych przypadków, ale chcesz uniknąć ostrzeżeń o metodach brakujących w czasie kompilacji, możesz użyć dyrektywy @dynamic zamiast @synthesize.
...
Użycie dyrektywy @dynamic zasadniczo mówi kompilatorowi: „nie martw się, metoda jest w drodze”.
Z @synthesize
drugiej strony dyrektywa generuje dla ciebie metody akcesora w czasie kompilacji (chociaż, jak zauważono w sekcji „Miksowanie syntetycznych i niestandardowych akcesoriów”, jest elastyczna i nie generuje metod, jeśli którekolwiek są zaimplementowane).
Jak powiedzieli inni, zazwyczaj używasz @synthesize, aby kompilator wygenerował dla ciebie gettery i / lub ustawienia, a @dynamic, jeśli masz zamiar je napisać.
Jest jeszcze inny subtelność jeszcze wymienić: @synthesize będzie pozwalają zapewnić implementację siebie, albo z getter i setter. Jest to przydatne, jeśli chcesz zaimplementować moduł pobierający tylko w celu uzyskania dodatkowej logiki, ale pozwól kompilatorowi wygenerować moduł ustawiający (który dla obiektów jest zwykle nieco trudniejszy do napisania).
Jednak jeśli napiszesz implementację dla akcesorium @ syntezowanego, to musi ona być jeszcze poparta prawdziwym polem (np. Jeśli piszesz -(int) getFoo();
, musisz mieć int foo;
pole). Jeśli wartość jest wytwarzana przez coś innego (np. Obliczana z innych pól), musisz użyć @dynamic.
@dynamic
jeśli zamierzasz je napisać sam” NIE, nie używasz dynamiki, jeśli sam je piszesz. @dynamic
wyłącza sprawdzanie kompilatora, aby upewnić się, że zostały zaimplementowane. Jeśli sam je zaimplementowałeś, chcesz, aby kompilator sprawdził.
@dynamic jest zwykle używany (jak wspomniano powyżej), gdy właściwość jest dynamicznie tworzona w czasie wykonywania. NSManagedObject robi to (dlaczego wszystkie jego właściwości są dynamiczne) - co eliminuje niektóre ostrzeżenia kompilatora.
Dobry przegląd dynamicznego tworzenia właściwości (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
oto przykład @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:"v@:@"];
} 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;
}
Zgodnie z dokumentacją:
@dynamic informuje kompilator, że metody dostępu są udostępniane w czasie wykonywania.
Po krótkim dochodzeniu dowiedziałem się, że udostępnienie metod akcesorium zastępuje dyrektywę @dynamic.
@synthesize mówi kompilatorowi, aby utworzył dla ciebie te akcesoria (getter i setter)
@property informuje kompilator, że akcesory zostaną utworzone i że można uzyskać do nich dostęp za pomocą notacji kropkowej lub [komunikatu obiektowego]
Jedną rzeczą, którą chcę dodać, jest to, że jeśli właściwość zostanie zadeklarowana jako @dynamic, nie zajmie ona pamięci (potwierdziłem za pomocą instrumentu alokacji). Konsekwencją jest to, że możesz zadeklarować właściwość w kategorii klasy.
Zgodnie z dokumentacją Apple.
Używasz @synthesize
instrukcji w bloku implementacyjnym klasy, aby powiedzieć kompilatorowi, aby utworzył implementacje pasujące do specyfikacji podanej w @property
deklaracji.
@dynamic
Instrukcja służy do informowania kompilatora, aby pomijał ostrzeżenie, jeśli nie może znaleźć implementacji metod dostępu określonych w @property
deklaracji.
Więcej informacji:-