2009-07-21 2 views

ответ

708

@synthesize будет генерировать методы getter и setter для вашего имущества. @dynamic просто сообщает компилятору, что методы getter и setter реализованы не самим классом, а где-то в другом месте (например, суперкласс или будут предоставлены во время выполнения).

Использование для @dynamic - это, например, с подклассами NSManagedObject (CoreData) или когда вы хотите создать выход для свойства, определенного суперклассом, который не был определен как выход.

@dynamic также может использоваться для делегирования ответственности за внедрение аксессуаров. Если вы реализуете аксессуры самостоятельно в классе, вы обычно не используете @dynamic.

Супер класс:

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

Подкласс:

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

не 100% право; dynamic - это значение по умолчанию, если вы не устанавливаете ни @synthesize, ни @dynamic. указание @dynamic просто означает, что вы берете на себя ответственность за правильную реализацию аксессуаров свойств на основе подписи объявления свойства. – Kevlar

+67

Не совсем, @dynamic означает, что ответственность за реализацию аксессуаров делегирована. Если вы реализуете аксессуры самостоятельно в классе, вы обычно не используете @dynamic. – diederikh

+2

Я получал ошибки NSUnknownKeyException с моим динамическим свойством, когда я удалял строку '@ synhesize' (Xcode 3.2 давал мне ошибку b/c. У меня не было подходящего ivar для моего @property). Добавление '@ dynamic' исправило проблему - теперь компилируется и выполняется. Благодаря! – pix0r

206

Посмотрите на this article; под заголовком «Методы, предоставленные во время выполнения»:

Некоторые аксессоры создаются динамически во время выполнения, например, некоторые из них используются в классе NSManagedObject от CoreData. Если вы хотите объявить и использовать свойства для этих случаев, но хотите избежать предупреждений о методах, отсутствующих во время компиляции, вы можете использовать директиву @dynamic вместо @synthesize.

...

Использование @dynamic директивы по существу говорит компилятор «не беспокойтесь об этом, метод находится на пути.»

@synthesize директива, с другой стороны, создает методы доступа для вас во время компиляции (хотя, как отмечалось в «Mixing Синтезированные и пользовательских Accessors» раздела он является гибким и не создает методы для вас, если либо реализованы).

+25

Это morer-correcter человек. Этот ответ является единственным ответом, который говорит о методах, созданных во время выполнения, что, по-видимому, отражает дух намного больше, чем верхний проголосовавший ans atm. – bobobobo

+1

Каждый человек должен продвигать этот. –

+0

@AnkitSrivastava делает «динамический» создать ивар? – onmyway133

29

Как уже сказано, в общем, вы используете @synthesize иметь компилятор генерировать методы получения и/или настройки для вас, и @ если вы собираетесь писать их самостоятельно.

Есть еще одна уловка, о которой еще не упоминалось: @synthesize будет Позвольте вам представить себе реализацию, как геттера, так и сеттера. Это полезно, если вы хотите только реализовать getter для некоторой дополнительной логики, но пусть компилятор сгенерирует setter (который для объектов обычно немного сложнее писать самостоятельно).

Однако, если вы пишете реализацию для асинхронного доступа @ synhesize'd, она все равно должна поддерживаться реальным полем (например, если вы пишете -(int) getFoo();, вы должны иметь поле int foo;). Если значение генерируется чем-то другим (например, рассчитано из других полей), вы должны использовать @dynamic.

+2

+1 для упоминания важной разницы: @dynamic позволяет создавать аксессоры для переменных, не определенных в вашем интерфейсе класса, и путем самоанализа. – mahboudz

+24

"и' @ dynamic', если вы собираетесь написать их самостоятельно. «Нет, вы НЕ используете динамические, если пишете их самостоятельно. '@ dynamic' отключает проверку компилятора, чтобы убедиться, что вы их реализовали. Если вы сами их реализовали, вы хотите, чтобы компилятор проверял. – user102008

14

@ dynamic обычно используется (как было сказано выше), когда свойство динамически создается во время выполнения. NSManagedObject делает это (почему все его свойства являются динамическими), что подавляет некоторые предупреждения компилятора.

Хороший обзор о том, как создавать свойства динамически (без NSManagedObject и CoreData :, см: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html#//apple_ref/doc/uid/TP40008048-CH102-SW1

6

Одно хочу добавить, что если свойство объявляется как @dynamic он не будет занимать память (I . подтвердили с инструментом выделения) следствием является то, что вы можете объявить свойство в классе категории

+0

Если я переопределяю свойство setter в категории и сделаю его динамическим, это гарантирует, что переопределение будет использоваться во время выполнения, а не в настройке родительского класса? Из документов Apple: «Если имя метода, объявленного в категории, совпадает с методом в исходном классе ... поведение не определено в отношении того, какая реализация метода используется во время выполнения». –

+0

Нет, я думаю, что поведение по-прежнему не определено. Создание свойства в динамике категории не изменяет приоритет времени выполнения метода set setter. –

13

here is пример @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:"[email protected]:@"]; 
    } 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; 
} 
9

согласно документации:.

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

@dynamic сообщает компилятору, что методы доступа предоставляются во время выполнения.

С небольшим расследованием я узнал, что предоставление методов доступа заменяет директиву @dynamic.

@synthesize сообщает компилятору, чтобы создать эти аксессоров для вас (геттер и сеттер)

@property сообщает компилятору, который будет создан в аксессоров, и которые могут быть доступны с точечной нотации или [объекта сообщения]

0

Согласно документации Apple.

Вы используете @synthesize заявление в блоке реализации класса за, чтобы сообщить компилятору создавать реализации, которые соответствуют спецификации, которую вы дали в @property декларации.

Вы используете оператор @dynamic, чтобы сообщить компилятору, чтобы он подал предупреждение, если он не может найти реализацию методов доступа, указанных в объявлении @property.

Дополнительная информация: -

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

Смежные вопросы