Respuestas:
@synthesize generará métodos getter y setter para su propiedad. @dynamic solo le dice al compilador que los métodos getter y setter no son implementados por la clase en sí sino en otro lugar (como la superclase o se proporcionarán en tiempo de ejecución).
Los usos de @dynamic son, por ejemplo, con subclases de NSManagedObject
(CoreData) o cuando desea crear una salida para una propiedad definida por una superclase que no se definió como una salida.
@dynamic también se puede usar para delegar la responsabilidad de implementar los accesos. Si implementa los accesores usted mismo dentro de la clase, normalmente no usa @dynamic.
Super clase:
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
Subclase:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
NSUnknownKeyException
errores con mi propiedad dinámica cuando eliminé la @synthesize
línea (Xcode 3.2 me estaba dando un error b / c no tenía ivar coincidente para mi @property). Agregar @dynamic
solucionó el problema: compila y funciona bien ahora. ¡Gracias!
@property
elementos que no tienen @synthesize
ni @dynamic
se sintetizarán automáticamente. Para cada propiedad, se creará un ivar con un guión bajo, por ejemplo _propertyName
, junto con el captador y definidor apropiado.
Echa un vistazo a este artículo ; bajo el título "Métodos proporcionados en tiempo de ejecución":
Algunos accesos se crean dinámicamente en tiempo de ejecución, como algunos utilizados en la clase NSManagedObject de CoreData. Si desea declarar y usar propiedades para estos casos, pero quiere evitar advertencias sobre los métodos que faltan en el momento de la compilación, puede usar la directiva @dynamic en lugar de @synthesize.
...
El uso de la directiva @dynamic esencialmente le dice al compilador "no te preocupes por eso, un método está en camino".
La @synthesize
directiva, por otro lado, genera los métodos de acceso para usted en el momento de la compilación (aunque, como se señaló en la sección "Mezcla de accesores sintetizados y personalizados", es flexible y no genera métodos para usted si se implementan).
Como han dicho otros, en general usa @synthesize para que el compilador genere los captadores y / o configuraciones para usted, y @dynamic si va a escribirlos usted mismo.
Hay otra sutileza aún no mencionada: @synthesize le permitirá proporcionar una implementación usted mismo, ya sea de un getter o un setter. Esto es útil si solo desea implementar el getter para obtener una lógica adicional, pero permite que el compilador genere el setter (que, para los objetos, generalmente es un poco más complejo de escribir usted mismo).
Sin embargo, si escribe una implementación para un descriptor de acceso @ sintetizado, aún debe estar respaldado por un campo real (por ejemplo, si escribe -(int) getFoo();
debe tener un int foo;
campo). Si el valor está siendo producido por otra cosa (por ejemplo, calculado a partir de otros campos), entonces debe usar @dynamic.
@dynamic
si vas a escribirlos tú mismo" No, NO utilizas dinámico si los escribes tú mismo. @dynamic
apaga la comprobación del compilador para asegurarse de que los implementó. Si los implementó usted mismo, desea que el compilador verifique.
@dynamic se usa típicamente (como se ha dicho anteriormente) cuando una propiedad se crea dinámicamente en tiempo de ejecución. NSManagedObject hace esto (por qué todas sus propiedades son dinámicas), lo que suprime algunas advertencias del compilador.
Para obtener una buena descripción general sobre cómo crear propiedades dinámicamente (sin NSManagedObject y CoreData :, consulte: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#// apple_ref / doc / uid / TP40008048-CH102-SW1
Aquí hay un ejemplo 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;
}
Según la documentación:
@dynamic le dice al compilador que los métodos de acceso se proporcionan en tiempo de ejecución.
Con un poco de investigación descubrí que proporcionar métodos de acceso anula la directiva @dynamic.
@synthesize le dice al compilador que cree esos accesores para usted (getter y setter)
@property le dice al compilador que se crearán los accesos, y que se puede acceder con la notación de punto o [mensaje de objeto]
Una cosa que quiero agregar es que si una propiedad se declara como @dynamic, no ocupará memoria (confirme con el instrumento de asignación). Una consecuencia es que puede declarar propiedades en la categoría de clase.
Según la documentación de Apple.
Utiliza la @synthesize
instrucción en el bloque de implementación de una clase para indicarle al compilador que cree implementaciones que coincidan con la especificación que proporcionó en la @property
declaración.
Utiliza la @dynamic
instrucción para indicarle al compilador que suprima una advertencia si no puede encontrar una implementación de métodos de acceso especificados por una @property
declaración.
Más información:-