570 votes

@synthétiser vs @dynamique, quelles sont les différences?

Quelles sont les différences entre la mise en œuvre d'un @property avec @dynamic ou @synthesize?

751voto

diederikh Points 17459

@synthétiser va générer les méthodes getter et setter pour votre propriété. @dynamique indique au compilateur que le getter et setter sont pas mis en œuvre par la classe elle-même, mais quelque part d'autre (comme la super-classe ou seront fournis au moment de l'exécution).

Utilise pour @dynamiques sont par exemple avec des sous-classes de NSManagedObject (CoreData) ou lorsque vous souhaitez créer un débouché pour une propriété définie par une super-classe qui n'était pas définie comme une prise de courant:

Super classe:

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

Sous-classe:

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

214voto

Alex Rozanski Points 26107

Jetez un oeil à cet article; sous la rubrique "Méthodes fournies au moment de l'exécution":

Certains accesseurs sont créés dynamiquement à l'exécution, comme certains de ceux utilisés dans CoreData de NSManagedObject classe. Si vous souhaitez déclarer et utiliser les propriétés de ces cas, mais que vous voulez éviter les mises en garde sur les méthodes manquantes au moment de la compilation, vous pouvez utiliser le @dynamique de la directive au lieu de @synthétiser.

...

À l'aide de @dynamique de la directive indique essentiellement le compilateur "ne vous inquiétez pas à ce sujet, une méthode est sur le chemin."

L' @synthesize directive, d'autre part, génère les méthodes d'accès pour vous au moment de la compilation (bien que, comme indiqué dans le "Mélange Synthétisés et Personnalisé Accesseurs de la section" elle est souple et ne génère pas de méthodes pour vous si sont mis en œuvre).

32voto

philsquared Points 13547

Comme d'autres l'ont dit, en général, vous utilisez @synthétiser pour le compilateur de générer les getters et/ ou des paramètres pour vous, et @dynamique si vous allez à les écrire vous-même.

Il y a une autre subtilité est pas encore mentionné: @synthétiser va vous permettre de fournir une implémentation de vous-même, soit d'un getter ou un setter. Ceci est utile si vous ne voulez à mettre en œuvre la lecture pour un peu de logique, mais de permettre au compilateur de générer le setter (qui, pour les objets, est généralement un peu plus complexe à écrire vous-même).

Toutefois, si vous écrivez une application pour un @synthétiser avais accesseur il doit encore être soutenu par un champ réel (par exemple, si vous écrivez -(int) getFoo(); vous devez avoir un int foo; champ). Si la valeur est produit par quelque chose d'autre (par exemple, calculée à partir d'autres domaines), alors vous devez utiliser @dynamique.

14voto

mifortin Points 331

@dynamique est généralement utilisé (comme il a été dit ci-dessus) lorsqu'un bien est créé dynamiquement à l'exécution. NSManagedObject est-ce (pourquoi toutes ses propriétés sont dynamiques) -- qui supprime certains avertissements du compilateur.

Pour un bon aperçu sur la façon de créer des propriétés dynamiquement (sans NSManagedObject et CoreData:, voir: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#//apple_ref/doc/uid/TP40008048-CH102-SW1

14voto

alisher3d Points 61

voici l'exemple de @dynamique

#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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X