Quais são as diferenças entre implementar @property
com @dynamic
ou @synthesize
?
@synthesize irá gerar methods getter e setter para sua propriedade. @dynamic apenas informa ao compilador que os methods getter e setter são implementados não pela própria class, mas em algum outro lugar (como a superclass ou será fornecido em tempo de execução).
Os usos para @dynamic são, por exemplo, com subclasss de NSManagedObject
(CoreData) ou quando você deseja criar uma saída para uma propriedade definida por uma superclass que não foi definida como uma saída.
O @dynamic também pode ser usado para delegar a responsabilidade de implementar os acessadores. Se você implementar os acessadores você mesmo dentro da class, então você normalmente não usa @dynamic.
Super class:
@property (nonatomic, retain) NSButton *someButton; ... @synthesize someButton;
Subclass:
@property (nonatomic, retain) IBOutlet NSButton *someButton; ... @dynamic someButton;
Dê uma olhada neste artigo ; sob o título “Métodos fornecidos em tempo de execução”:
Alguns acessadores são criados dinamicamente em tempo de execução, como certos usados na class NSManagedObject do CoreData. Se você deseja declarar e usar propriedades para esses casos, mas deseja evitar avisos sobre os methods ausentes em tempo de compilation, é possível usar a diretiva @dynamic em vez de @synthesize.
…
Usando a diretiva @dynamic essencialmente diz ao compilador “não se preocupe, um método está a caminho”.
A diretiva @synthesize
, por outro lado, gera os methods de access para você em tempo de compilation (embora, como observado na seção “Misturando Sintetizados e Custom Accessors”, seja flexível e não gere methods para você, se ambos forem implementados).
Como outros já disseram, em geral você usa @synthesize para que o compilador gere os getters e / ou settings para você, e @dynamic se você vai escrevê-los você mesmo.
Há outra sutileza ainda não mencionada: o @synthesize permitirá que você forneça uma implementação, seja de um getter ou de um setter. Isso é útil se você quiser implementar o getter somente para alguma lógica extra, mas deixe o compilador gerar o setter (que, para objects, é geralmente um pouco mais complexo para escrever você mesmo).
No entanto, se você escrever uma implementação para um accessr @ synthesize’d, ele ainda deve ser suportado por um campo real (por exemplo, se você escrever -(int) getFoo();
você deve ter um campo int foo;
). Se o valor está sendo produzido por alguma outra coisa (por exemplo, calculado a partir de outros campos), então você tem que usar @ dinâmica.
@ Dinâmico é normalmente usado (como foi dito acima) quando uma propriedade está sendo dinamicamente criada em tempo de execução. NSManagedObject faz isso (por que todas as suas propriedades são dinâmicas) – o que suprime alguns avisos do compilador.
Para uma boa visão geral sobre como criar propriedades dinamicamente (sem NSManagedObject e CoreData :, consulte: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#// apple_ref / doc / uid / TP40008048-CH102-SW1
aqui está um exemplo de @dynamic
#import @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; }
Conforme a documentação:
@dynamic informa ao compilador que os methods de access são fornecidos no tempo de execução.
Com um pouco de investigação, descobri que fornecer methods de access sobrescrevem a diretiva @dynamic.
@synthesize diz ao compilador para criar esses acessadores para você (getter e setter)
@property informa ao compilador que os acessadores serão criados e que podem ser acessados com a notação de ponto ou [mensagem do object]
Uma coisa que queremos adicionar é que, se uma propriedade for declarada como @ dinâmica, ela não ocupará memory (confirmei com o instrumento de alocação). Uma consequência é que você pode declarar propriedade na categoria de class.
De acordo com a documentação da Apple.
Você usa a instrução @synthesize
no bloco de implementação de uma class para dizer ao compilador para criar implementações que correspondam à especificação que você forneceu na declaração @property
.
Você usa a instrução @dynamic
para dizer ao compilador para suprimir um aviso se não puder encontrar uma implementação de methods de access especificados por uma declaração @property
.
Mais informações:-