@synthesize против @dynamic, в чем различия?

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

вопрос задан 21.07.2009
nico
4311 репутация

8 ответов


  • 719 рейтинг

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

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

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

    Суперкласс:

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

    Подкласс:

    @property (nonatomic, retain) IBOutlet NSButton *someButton;
    ...
    @dynamic someButton;
    
    ответ дан diederikh, с репутацией 23994, 21.07.2009
  • 209 рейтинг

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

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

    . , ,

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

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

    ответ дан Alex Rozanski, с репутацией 35501, 21.07.2009
  • 29 рейтинг

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

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

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

    ответ дан philsquared, с репутацией 17414, 21.07.2009
  • 14 рейтинг

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

    Хороший обзор того, как динамически создавать свойства (без NSManagedObject и CoreData:, см .: http: // developer. яблоко. ком / библиотека / ИОС / # документация / Какао / Концептуальный / ObjCRuntimeGuide / Статьи / ocrtDynamicResolution. html # // apple_ref / doc / uid / TP40008048-CH102-SW1

    ответ дан mifortin, с репутацией 391, 25.11.2011
  • 13 рейтинг

    вот пример @dynamic

    #import 
    
    @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;
    }
    
    ответ дан mirror, с репутацией 305, 11.09.2013
  • 9 рейтинг

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

    https: // разработчик. яблоко. ком / библиотека / Mac / документация / какао / концептуальным / ObjCRuntimeGuide / Статьи / ocrtDynamicResolution. HTML

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

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

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

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

    ответ дан user1447414, с репутацией 477, 3.12.2013
  • 6 рейтинг

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

    ответ дан Yingpei Zeng, с репутацией 495, 13.05.2013
  • 1 рейтинг

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

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

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

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

    https: // разработчик. яблоко. ком / библиотека / ИОС / Документация / Общий / Концептуальный / DevPedia-CocoaCore / DeclaredProperty. HTML

    ответ дан arango_86, с репутацией 1325, 16.12.2015