@synthesize vs @dynamic,有什么区别?

@dynamic@synthesize实现@dynamic之间有什么区别?

@synthesize会为你的属性生成getter和setter方法。 @dynamic只是告诉编译器,getter和setter方法不是由类本身实现,而是在其他地方(比如超类,或者在运行时提供)。

用于@dynamic的例如是NSManagedObject (CoreData)的子类,或者当你想为一个没有被定义为sockets的超类定义的属性创build一个sockets。

@dynamic也可以用来委托实现访问器的责任。 如果你在类中自己实现访问器,那么你通常不使用@dynamic。

超级class:

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

子类:

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

看看这篇文章 ; 在“运行时提供的方法”标题下:

有些访问器是在运行时dynamic创build的,例如CoreData的NSManagedObject类中使用的某些访问器。 如果要声明和使用这些情况的属性,但是希望避免在编译时丢失有关方法的警告,则可以使用@dynamic指令而不是@synthesize。

使用@dynamic指令本质上告诉编译器“不用担心,一种方法正在进行中”。

另一方面,@ @synthesize指令在编译时为您生成访问器方法(尽pipe如“混合合成和自定义访问器”一节中所述,它是灵活的,如果实现的话不会为您生成方法)。

正如其他人所说的,一般来说,你使用@synthesize让编译器为你生成getter和/或设置,如果你要自己编写@dynamic。

还有一个微妙之处还没有提到:@synthesize会让你自己提供一个实现,或者是一个getter或者一个setter。 如果您只想为某些额外的逻辑实现getter,但是让编译器生成setter(对于对象来说,通常会自己写更复杂一点),这是非常有用的。

但是,如果您为@ synthesize的访问器编写实现,则它仍然必须由实际字段支持(例如,如果您编写了-(int) getFoo();您必须具有int foo;字段)。 如果值是由别的东西产生的(例如从其他字段计算),那么你必须使用@dynamic。

在运行时dynamic创build属性时,通常会使用@dynamic(如上所述)。 NSManagedObject这样做(为什么它的所有属性都是dynamic的) – 这会抑制一些编译器警告。

有关如何dynamic创build属性的详细信息(不包括NSManagedObject和CoreData :,请参阅: http : //developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#// apple_ref / DOC / UID / TP40008048-CH102-SW1

这里是 @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; } 

根据文件:

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

@dynamic告诉编译器,访问器方法是在运行时提供的。

通过一些调查,我发现提供访问器方法会覆盖@dynamic指令。

@synthesize告诉编译器为你创build访问器(getter和setter)

@property告诉编译器访问器将被创build,并且可以用点符号或[对象消息]

有一点要补充的是,如果一个属性声明为@dynamic它不会占用内存(我用分配仪器确认)。 结果是你可以在类的类中声明属性。

按照苹果文档。

您可以在类的实现块中使用@synthesize语句来告诉编译器创build符合您在@property声明中给出的规范的实现。

如果@dynamic@dynamic声明指定的访问器方法的实现,则可以使用@dynamic语句告诉编译器取消警告。

更多信息:-

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