Question @synthesize vs @dynamic, quelles sont les différences?


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


537
2017-07-21 17:12


origine


Réponses:


@synthesize va générer des méthodes getter et setter pour votre propriété. @dynamic indique simplement au compilateur que les méthodes getter et setter ne sont pas implémentées par la classe elle-même mais ailleurs (comme la superclasse ou seront fournies lors de l'exécution).

Les utilisations de @dynamic sont, par exemple, avec des sous-classes de NSManagedObject (CoreData) ou lorsque vous souhaitez créer un point de vente pour une propriété définie par une superclasse qui n'a pas été définie en tant que point de vente.

@dynamic peut également être utilisé pour déléguer la responsabilité de l'implémentation des accesseurs. Si vous implémentez vous-même les accesseurs dans la classe, vous n'utilisez normalement pas @dynamic.

Super classe:

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

Sous-classe:

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

718
2017-07-21 17:21



Jeter un coup d'œil à Cet article; sous la rubrique "Méthodes fournies lors de l'exécution":

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

...

L'utilisation de la directive @dynamic indique essentiellement au compilateur "ne vous en faites pas, une méthode est en route".

le @synthesize D'autre part, la directive génère les méthodes d'accès pour vous au moment de la compilation (bien que, comme indiqué dans la section «Mélanger les synthétiseurs et les accesseurs personnalisés», elle soit flexible et ne génère pas de méthodes si l'une est implémentée).


209
2017-07-21 17:20



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 les écrire vous-même.

Il y a une autre subtilité non encore mentionnée: @synthesize volonté laissez-vous fournir vous-même une implémentation, soit d'un getter ou d'un setter. Ceci est utile si vous voulez seulement implémenter le getter pour une logique supplémentaire, mais laissez le compilateur générer le setter (qui, pour les objets, est généralement un peu plus complexe à écrire vous-même).

Cependant, si vous écrivez une implémentation pour un accesseur @ synthesize'd, il doit toujours être soutenu par un vrai champ (par exemple, si vous écrivez -(int) getFoo(); vous devez avoir un int foo; champ). Si la valeur est produite par un autre élément (par exemple calculé à partir d'autres champs), vous devez utiliser @dynamic.


29
2017-07-21 18:04



@dynamic est généralement utilisé (comme cela a été dit plus haut) lorsqu'une propriété est créée dynamiquement au moment de l'exécution. NSManagedObject fait cela (pourquoi toutes ses propriétés sont dynamiques) - ce 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


14
2017-11-25 21:30



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

13
2017-09-11 09:27



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 fournies lors de l'exécution.

Avec un peu d'enquête, j'ai découvert que la fourniture de méthodes d'accès surchargeait la directive @dynamic.

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

@property dit au compilateur que les accesseurs seront créés, et que l'on peut y accéder avec la notation pointée ou [message d'objet]


9
2017-12-03 18:25



Une chose à ajouter est que si une propriété est déclarée comme @dynamic, elle n'occupera pas de mémoire (j'ai confirmé avec l'instrument d'allocation). Une conséquence est que vous pouvez déclarer la propriété dans la catégorie de la classe.


6
2018-05-13 09:14



Selon la documentation Apple.

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

Vous utilisez le @dynamic instruction de dire au compilateur de supprimer un avertissement s'il ne trouve pas une implémentation des méthodes d'accès spécifiées par un @property déclaration.

Plus d'informations:-

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


0
2017-12-16 11:21