Question

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

Était-ce utile?

La solution

@synthesize va générer getter et setter pour votre propriété. @dynamic dit que le compilateur que les méthodes de lecture et de définition sont mises en œuvre non pas par la classe elle-même, mais un autre endroit (comme la superclasse ou seront fournis lors de l'exécution).

Utilisations pour @dynamic sont, par exemple avec sous-classes de NSManagedObject (CoreData) ou lorsque vous voulez créer une sortie pour une propriété définie par une superclasse qui n'a pas été définie comme une sortie.

@dynamic peut également être utilisé pour déléguer la responsabilité de la mise en œuvre des accesseurs. Si vous implémentez les accesseurs vous dans la classe, alors vous ne normalement pas utiliser @dynamic.

Super classe:

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

Sous-classe:

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

Autres conseils

Jetez un oeil à cet article ; sous la rubrique « Méthodes fournies lors de l'exécution »:

  

Certains accesseurs sont créés dynamiquement lors de l'exécution, tels que certains ceux utilisés dans la classe NSManagedObject de CoreData. Si vous voulez déclarer et d'utiliser des propriétés pour ces cas, mais que vous voulez éviter les avertissements sur les méthodes manquantes au moment de la compilation, vous pouvez utiliser la directive @dynamic au lieu de @synthesize.

     

...

     

Utilisation de la directive @dynamic indique essentiellement le compilateur « ne vous inquiétez pas à ce sujet, une méthode est sur le chemin. »

La directive @synthesize, d'autre part, génère les accesseurs pour vous au moment de la compilation (mais, comme indiqué dans la section « Mixing Synthétisé et accesseurs sur mesure », il est souple et ne génère pas de méthodes pour vous si soit sont mises en œuvre) .

Comme d'autres l'ont dit, en général, vous utilisez @synthesize pour que le compilateur génère les getters et / ou les paramètres pour vous et @dynamic si vous allez écrire vous-même.

Il y a une autre subtilité pas encore mentionné: @synthesize vous permettent de fournir une implémentation vous, soit d'un getter ou un setter. Ceci est utile si vous ne souhaitez que pour mettre en œuvre le getter pour une certaine logique supplémentaire, mais laisser le compilateur générer le setter (qui, pour des objets, est généralement un peu plus complexe pour vous écrire).

Cependant, si vous faites écrire une implémentation pour un @ synthesize'd accesseur il doit encore être soutenu par un champ réel (par exemple, si vous écrivez -(int) getFoo(); vous devez avoir un champ int foo;). Si la valeur est produit par quelque chose d'autre (par exemple calculé à partir d'autres champs), vous devez utiliser @dynamic.

@dynamic est généralement utilisé (comme cela a été dit ci-dessus) quand une propriété est créée dynamiquement à l'exécution. NSManagedObject fait cela (pourquoi toutes ses propriétés sont dynamiques) -. Qui supprime certains avertissements du compilateur

Pour une bonne vue d'ensemble 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

ici est par exemple de @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;
}

Selon la documentation:

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

@dynamic indique au compilateur que les méthodes d'accès sont fournis lors de l'exécution.

Avec un peu d'investigation, j'ai découvert qu'en fournissant des méthodes accesseurs remplacent la directive @dynamic.

@synthesize indique au compilateur de créer les accesseurs pour vous (getter et setter)

@property indique au compilateur que les accesseurs seront créés, et qui est accessible avec la notation de point ou [message d'objet]

Une chose est voulez ajouter que si une propriété est déclarée comme @dynamic il ne sera pas occuper la mémoire (je confirme avec l'instrument d'allocation). Une conséquence est que vous pouvez déclarer la propriété dans la catégorie de classe.

Selon la documentation Apple.

Vous utilisez l'instruction @synthesize dans le bloc de mise en œuvre d'une classe pour indiquer au compilateur pour créer des implémentations correspondant à la spécification que vous avez donné dans la déclaration de @property.

Vous utilisez l'instruction @dynamic pour indiquer au compilateur de supprimer un avertissement si elle ne peut pas trouver une mise en œuvre de méthodes d'accès spécifiées par une déclaration de @property.

Plus d'infos: -

https://developer.apple. com / bibliothèque / ios / documentation / général / conceptuel / DevPedia-CocoaCore / DeclaredProperty.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top