Вопрос

Каковы различия между внедрением @property с @dynamic или @synthesize?

Это было полезно?

Решение

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

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

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

Супер класс:

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

Подкласс:

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

Другие советы

Взгляните на эта статья;под заголовком "Методы, предоставляемые во время выполнения":

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

...

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

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

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

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

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

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

Хороший обзор того, как создавать свойства динамически (без 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 сообщает компилятору создать для вас эти средства доступа (getter и setter)

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

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

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

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

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

Подробная информация:-

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top