Respostas:
O @synthesize gerará métodos getter e setter para sua propriedade. O @dynamic diz ao compilador que os métodos getter e setter são implementados não pela própria classe, mas em algum outro lugar (como a superclasse ou será fornecida em tempo de execução).
Os usos para @dynamic são, por exemplo, com subclasses de NSManagedObject
(CoreData) ou quando você deseja criar uma saída para uma propriedade definida por uma superclasse 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ê implementa os acessadores dentro da classe, normalmente não usa @dynamic.
Super classe:
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
Subclasse:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
NSUnknownKeyException
erros com minha propriedade dinâmica quando removi a @synthesize
linha (o Xcode 3.2 estava me dando um erro porque eu não tinha ivar correspondente para minha @ propriedade). A adição @dynamic
corrigiu o problema - compila e roda bem agora. Obrigado!
@property
itens que não possuem @synthesize
nem @dynamic
serão sintetizados automaticamente. Para cada propriedade, um ivar com um sublinhado à esquerda, por exemplo, _propertyName
será criado, juntamente com o getter e o setter apropriados.
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 alguns usados na classe NSManagedObject do CoreData. Se você deseja declarar e usar propriedades para esses casos, mas deseja evitar avisos sobre métodos ausentes no momento da compilação, use a diretiva @dynamic em vez de @synthesize.
...
O uso da diretiva @dynamic diz essencialmente ao compilador "não se preocupe, um método está a caminho".
A @synthesize
diretiva, por outro lado, gera os métodos de acessador para você em tempo de compilação (embora, conforme observado na seção "Misturando acessores sintetizados e personalizados", seja flexível e não gere métodos para você, se algum deles estiver implementado).
Como outros já disseram, em geral você usa @synthesize para que o compilador gere os getters e / ou configurações para você e @dynamic se você mesmo os escrever.
Há outra sutileza ainda não mencionada: @synthesize permitirá que você forneça uma implementação, seja de um getter ou de um setter. Isso é útil se você deseja implementar o getter apenas para uma lógica extra, mas permite que o compilador gere o setter (que, para objetos, geralmente é um pouco mais complexo de se escrever).
No entanto, se você escrever uma implementação para um acessador @ synthesize'd, ainda deverá ser apoiada por um campo real (por exemplo, se você escrever, -(int) getFoo();
deverá ter um int foo;
campo). Se o valor estiver sendo produzido por outra coisa (por exemplo, calculado a partir de outros campos), você deverá usar @dynamic.
@dynamic
se você mesmo escrever" Não, você NÃO usa dinâmico se você mesmo os escrever. @dynamic
desativa a verificação do compilador para garantir que você os implementou. Se você os implementou, deseja que o compilador verifique.
@dynamic é normalmente usado (como foi dito acima) quando uma propriedade está sendo criada dinamicamente em tempo de execução. O NSManagedObject faz isso (por que todas as suas propriedades são dinâmicas) - que suprimem alguns avisos do compilador.
Para obter uma boa visão geral de 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 <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;
}
Conforme a documentação:
@dynamic informa ao compilador que os métodos acessadores são fornecidos em tempo de execução.
Com um pouco de investigação, descobri que o fornecimento de métodos de acessor substitui a diretiva @dynamic.
O @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 de objeto]
Uma coisa a acrescentar é que, se uma propriedade for declarada como @dynamic, ela não ocupará memória (confirmei com o instrumento de alocação). Uma conseqüência é que você pode declarar propriedade na categoria de classe.
Conforme a documentação da Apple.
Você usa a @synthesize
instrução no bloco de implementação de uma classe para informar ao compilador para criar implementações que correspondem à especificação que você forneceu na @property
declaração.
Você usa a @dynamic
instrução para instruir o compilador a suprimir um aviso se ele não conseguir encontrar uma implementação dos métodos de acessador especificados por uma @property
declaração.
Mais informações:-