Antworten:
@synthesize generiert Getter- und Setter-Methoden für Ihre Immobilie. @dynamic teilt dem Compiler lediglich mit, dass die Getter- und Setter-Methoden nicht von der Klasse selbst implementiert werden, sondern an einer anderen Stelle (wie der Oberklasse oder zur Laufzeit bereitgestellt).
Verwendungen für @dynamic sind z. B. mit Unterklassen von NSManagedObject
(CoreData) oder wenn Sie einen Ausgang für eine Eigenschaft erstellen möchten, die von einer Oberklasse definiert wurde, die nicht als Ausgang definiert wurde.
@dynamic kann auch verwendet werden, um die Verantwortung für die Implementierung der Accessoren zu delegieren. Wenn Sie die Accessoren selbst in der Klasse implementieren, verwenden Sie normalerweise nicht @dynamic.
Super Klasse:
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
Unterklasse:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
NSUnknownKeyException
Fehler mit meiner dynamischen Eigenschaft erhalten, als ich die @synthesize
Zeile entfernt habe (Xcode 3.2 hat mir einen Fehler gemeldet, da ich kein passendes ivar für meine @ Eigenschaft hatte). Das Hinzufügen @dynamic
des Problems wurde behoben - kompiliert und läuft jetzt einwandfrei. Vielen Dank!
@property
Elemente, die weder automatisch synthetisiert wurden, @synthesize
noch @dynamic
automatisch synthetisiert. Für jede Eigenschaft wird ein Ivar mit einem führenden Unterstrich erstellt, z. B. _propertyName
zusammen mit dem entsprechenden Getter und Setter.
Schauen Sie sich diesen Artikel an . unter der Überschrift "Zur Laufzeit bereitgestellte Methoden":
Einige Accessoren werden zur Laufzeit dynamisch erstellt, z. B. bestimmte, die in der NSManagedObject-Klasse von CoreData verwendet werden. Wenn Sie Eigenschaften für diese Fälle deklarieren und verwenden möchten, aber Warnungen vor Methoden vermeiden möchten, die zur Kompilierungszeit fehlen, können Sie die Direktive @dynamic anstelle von @synthesize verwenden.
...
Die Verwendung der @ dynamic-Direktive sagt dem Compiler im Wesentlichen: "Mach dir keine Sorgen, eine Methode ist unterwegs."
Die @synthesize
Direktive hingegen generiert die Zugriffsmethoden zur Kompilierungszeit für Sie (obwohl sie, wie im Abschnitt "Mischen von synthetisierten und benutzerdefinierten Zugriffsmethoden" angegeben, flexibel ist und keine Methoden für Sie generiert, wenn beide implementiert sind).
Wie andere bereits gesagt haben, verwenden Sie im Allgemeinen @synthesize, damit der Compiler die Getter und / oder Einstellungen für Sie generiert, und @dynamic, wenn Sie sie selbst schreiben möchten.
Es gibt noch eine weitere Subtilität, die noch nicht erwähnt wurde: Mit @synthesize können Sie selbst eine Implementierung eines Getters oder eines Setters bereitstellen. Dies ist nützlich, wenn Sie den Getter nur für eine zusätzliche Logik implementieren möchten, den Compiler jedoch den Setter generieren lassen möchten (was für Objekte normalerweise etwas komplexer ist, sich selbst zu schreiben).
Wenn Sie jedoch eine Implementierung für einen @ synthetize'd-Accessor schreiben, muss diese weiterhin von einem realen Feld unterstützt werden (z. B. wenn Sie schreiben -(int) getFoo();
, müssen Sie ein int foo;
Feld haben). Wenn der Wert von etwas anderem erzeugt wird (z. B. aus anderen Feldern berechnet), müssen Sie @dynamic verwenden.
@dynamic
wenn Sie sie selbst schreiben wollen" Nein, Sie verwenden KEINE Dynamik, wenn Sie sie selbst schreiben. @dynamic
Deaktiviert die Compilerprüfung, um sicherzustellen, dass Sie sie implementiert haben. Wenn Sie sie selbst implementiert haben, soll der Compiler dies überprüfen.
@dynamic wird normalerweise (wie oben erwähnt) verwendet, wenn eine Eigenschaft zur Laufzeit dynamisch erstellt wird. NSManagedObject führt dies aus (warum alle seine Eigenschaften dynamisch sind) - wodurch einige Compiler-Warnungen unterdrückt werden.
Eine gute Übersicht zum dynamischen Erstellen von Eigenschaften (ohne NSManagedObject und CoreData:) finden Sie unter: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#// apple_ref / doc / uid / TP40008048-CH102-SW1
Hier ist ein Beispiel für @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;
}
Gemäß Dokumentation:
@dynamic teilt dem Compiler mit, dass die Zugriffsmethoden zur Laufzeit bereitgestellt werden.
Mit ein wenig Nachforschungen fand ich heraus, dass die Bereitstellung von Accessor-Methoden die @ dynamic-Direktive überschreibt.
@synthesize weist den Compiler an, diese Accessoren für Sie zu erstellen (Getter und Setter).
@property teilt dem Compiler mit, dass die Accessoren erstellt werden und dass mit der Punktnotation oder [Objektnachricht] darauf zugegriffen werden kann.
Eine Sache, die hinzugefügt werden soll, ist, dass eine Eigenschaft, die als @dynamic deklariert ist, keinen Speicher belegt (ich habe dies mit dem Zuweisungsinstrument bestätigt). Eine Konsequenz ist, dass Sie eine Eigenschaft in der Klassenkategorie deklarieren können.
Gemäß der Apple-Dokumentation.
Sie verwenden die @synthesize
Anweisung im Implementierungsblock einer Klasse, um den Compiler anzuweisen, Implementierungen zu erstellen, die der in der @property
Deklaration angegebenen Spezifikation entsprechen .
Sie verwenden die @dynamic
Anweisung, um den Compiler anzuweisen, eine Warnung zu unterdrücken, wenn er keine Implementierung von Zugriffsmethoden finden kann, die in einer @property
Deklaration angegeben sind.
Mehr Info:-