Когда я должен использовать @синтезировать прямо?

Насколько я знаю, так как в Xcode 4.4 на @синтезировать будет автоматически генерировать аксессоры свойств. Но только сейчас я прочитал образец кода о NSUndoManager, а в коде он заметил, что @синтезировать явно добавил. Как:

@interface RootViewController  ()

@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@property (nonatomic, strong) NSUndoManager *undoManager;

@end

@implementation RootViewController
//Must explicitly synthesize this
@synthesize undoManager;

Я чувствую себя сейчас озадачен... когда я должен добавить @синтезировать прямо в мой код?

Комментарии к вопросу (2)
Решение

Там'ы много ответов, но еще большая путаница. Я'будете пытаться навести порядок (или увеличить беспорядок, мы'll увидеть...)

  1. Позвольте's прекратите говорить о в Xcode. В XCode-это язь. Clang является компилятор. Эта особенность, которую мы обсуждаем называется autosynthesis свойств и это'ы цель-расширение языка C поддерживается лязг, которая используется по умолчанию компилятор используется в Xcode. <БР> Чтобы было понятнее, если вы переключитесь на ССЗ в Xcode, вы выиграли'т воспользоваться этой функцией (вне зависимости от версии Xcode.) Таким же образом, если вы используйте текстовый редактор и компилировать использовать Clang из командной строки, вы будете.

  2. Спасибо autosynthesis вы Don'т должны четко синтезировать имущества, поскольку оно будет автоматически синтезируемых компилятором как

@синтезировать имя_свойства = _propertyName

Однако, существует несколько исключений:

  • свойства ReadWrite с таможней геттер и сеттер

при предоставлении и геттер и сеттер пользовательские реализации, собственность выиграл'т быть автоматически синтезированы

  • свойство readonly с пользовательскими геттер

при предоставлении пользовательской реализации геттер для свойства readonly, это выиграл'т быть автоматически синтезированы

  • @динамически

при использовании @динамического имя_свойства, собственность выиграл'т быть автоматически синтезированы (очевидно, с @динамический " и " @синтезировать являются взаимоисключающими)

  • свойства, объявленные в @протоколу

когда соответствующий протокол, любое свойство протокола определяет, выиграл'т быть автоматически синтезированы

  • свойства, объявленные в категории

это дело, в котором директива@синтезировать не автоматически вставляется компилятором, но эти свойства не могут быть синтезированы самостоятельно. В то время как категории могут объявлять свойства, они не могут быть синтезированы вообще, поскольку невозможно создать Ивар. Для полноты картины, Я'МР добавить, что'его's все еще возможно поддельный синтез собственность, используя объективные-c времени выполнения.

  • переопределенные свойства (новый с лязгом-600.0.51, доставка с Xcode 6, спасибо Марку, школаüpmann)

при переопределении свойства суперкласса, вы должны явно синтезировать

Это's стоит отметить, что синтезирующие свойства автоматически синтезировать бэк-Ивар, так что если синтез собственность отсутствует, Ивар будет тоже отсутствует, если явно не объявлено.

За исключением последних трех случаях общая философия заключается в том, что всякий раз, когда вы вручную указываете все сведения о собственности (путем применения всех методов доступа или с помощью @динамичных) компилятор будет предполагать, что вам нужен полный контроль над собственностью и он будет отключить autosynthesis на нем.

Помимо случаев, перечисленных выше, только другое использование явного `@синтезировать бы указать другое имя Ивар. Однако конвенций имеют важное значение, поэтому мой совет Всегда используйте именования по умолчанию.

Комментарии (6)

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

@synthesize undoManager=_undoManager;

тогда вы сможете писать в коде что-то вроде :

[_undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter

Это общее соглашение.

если вы пишете

@synthesize undoManager;

вы будете иметь :

[undoManager doSomething]; // iVar
[self.undoManager doSomethingElse]; // Use generated getter

Лично я прекращаю с помощью@синтезировать, поскольку он's не обязательно больше. Для меня единственная причина, чтобы использовать@синтезировать состоит в том, чтобы связать Ивар на @недвижимости. Если вы хотите создать определенный геттер и сеттер для него. Но в данном куске кода нет Ивар, я думаю, что@синтезировать-это бесполезно. Но теперь я думаю, что новый вопрос "Когда использовать Ивар ?", и я'вэ никакой другой ответ чем-то "никогда" не для этого !

Комментарии (9)

Когда я должен добавить @синтезировать прямо в мой код?

Как правило, если это'обязательно: вы, вероятно, никогда не бил случай, когда он'ы нужны.

Там's в одном случае вы можете найти его полезным,.

Скажем, вы'вновь записав заказ геттер и сеттер, но хочу экземпляр переменной, чтобы поддержать это. (Для атомной собственность, это так просто, так как желающих пользовательский сеттер: компилятор написать геттер, если вы укажите сеттер для свойства одноатомных, но не атомную собственность).

Рассматривайте это:

@interface MyObject:NSObject
@property (copy) NSString *title;
@end

@implementation MyObject

- (NSString *)title {
    return _title;
}
- (void)setTitle:(NSString *)title {
    _title = [title copy];
}

@end

Это не будет работать, потому что _title не'т существуют. Вы'ве указан как геттер или сеттер, так что в Xcode (правильно) не'т создать экземпляр бэк переменную.

У вас есть два варианта, что делает его существование. Вы можете либо изменить @реализации этого:

@implementation MyObject {
    NSString *_title;
}

- (NSString *)title {
    return _title;
}
- (void)setTitle:(NSString *)title {
    _title = [title copy];
}

@end

Или изменить его к этому:

@implementation MyObject

@synthesize title = _title;

- (NSString *)title {
    return _title;
}
- (void)setTitle:(NSString *)title {
    _title = [title copy];
}

@end

Другими словами, хотя синтезировать для практических целей не надо*, он может быть использован для определение собственность-поддержка переменных экземпляра, когда вы'повторного предоставления геттер/сеттер. Вы можете решить, какая форма здесь вы хотите использовать.

В прошлом, я'вэ выступает указание переменной экземпляра в@реализации {}, но сейчас я думаю, что@синтезировать` пути является лучшим выбором, так как он удаляет избыточный тип и явно связывает бэк переменной в собственность:

  1. Измените свойство's, тип и экземпляр переменной's меняет тип.
  2. Изменить свою классификатором хранения (например, сделать ее слабой, а не сильной или сильным, а не слабым) и хранения изменения квалификации.
  3. Удалить или переименовать объект, а @синтезировать приведет к ошибке компиляции. Вы выиграли'т в конечном итоге с бродячими переменные экземпляра.

*-Я знаю один случай, где это было необходимо, касающимся разделения функций различных категорий в нескольких файлах. И я бы'т быть удивлены, если Apple исправляет это, или даже уже есть.

Комментарии (15)

ОК, когда вы создаете свойство...

@property NSString *name;

В Xcode автоматически синтезировать в Ивар, как будто они написаны...

@synthesize name = _name;

Это означает, что вы можете получить доступ к свойству с...

self.name;
// or
_name;

Либо будет работать, но только самостоятельно.имя на самом деле использует методы доступа.

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

Вы прекрасны, если вы просто переопределить сеттер или если вы просто переопределить геттер. Но если ты так поступишь, то компилятор выиграл'т понять его и нужно будет синтезировать его вручную.

Как правило, хотя большой палец.

Дон'т сделать Иварс. Просто используйте свойство. Дон'т синтезировать его.

Комментарии (8)

Синтез имущества требуется, когда дом был внесен в протокол. Он не будет автоматически синтезируются в интерфейсе реализации.

Комментарии (2)

Спасибо за разъяснение, что. У меня была похожая проблема.

@synthesize firstAsset, secondAsset, audioAsset;
@synthesize activityView;

Так что теперь, комментирует их, я прошел и заменить каждое вхождение, например

самовывоз.firstAsset кажется, я мог бы также использовать firstAsset, но я нахожу, что я скучаю по графе "" и слишком часто.

Комментарии (0)

В Xcode не'т нужна декларация явный @синтезировать.

Если вы Don'т писать@синтезировать его таким же, как делаю :

@synthesize manager = _manager;

Пример кода может'вэ были старые. Они'будете обновлять его в ближайшее время.

Вы можете получить доступ к свойствам, как :

[self.manager function];

Это яблоко's рекомендуемый конвенции. Я следую за ним, и я рекомендую вам сделать тоже!

Комментарии (4)