Могу ли я переопределить, как @synthesize работает в Objective C?
Я создаю базовый класс, который имеет флаг isDirty
. Он устанавливается каждый раз, когда изменяется одно из его свойств, но поскольку это базовый класс, он не знает, каковы его свойства. Так что в принципе, на каждом подклассе я должен переопределить каждый метод - set:
на что-то вроде этого:
- (id) setName:(NSString *)value {
if ([name isEqualToString:value]) {
return;
}
[name autorelease];
name = [value retain];
isDirty = YES; //Here's the important bit
}
Почти каждая строка этого-то, что автоматически синтезированный сеттер сделал бы. Есть ли способ, которым я могу переопределить то, что @synthesize
На самом деле создает?
Есть и другие варианты, которые я придумал, но все они кажутся гораздо более медленными во время выполнения, чем этот метод. Я думал о таких вещах, как добавление объекта, чтобы наблюдать за его собственными изменениями свойств, или создание универсальной функции, чтобы сделать все это и просто передать адрес в iVar и новое значение, но это все еще требует переопределения сеттера.
Есть идеи? Если это имеет значение, то это для приложения iPhone.
4 ответа:
Я не знаю способа, который позволит вам переопределить то, что делает @synthesize.
В конце концов, он используется для создания основных методов доступа-ie. те, которые не имеют определенного поведения.
Может быть, вам следует изучить кодирование значений ключей и наблюдение за значениями ключей?
Здесь несколько вопросов:
(1) Если вы беспокоитесь о производительности сеттера, вы не должны использовать-isEqualToString: в вашем сеттере. Вместо этого сделайте сравнение указателя, потому что это все, что имеет значение в данном контексте.
(2) Если у вас есть атрибут NSString, вы должны копировать на set. Копирование является бесплатным для неизменяемых строк и сохранит ваш бекон для изменяемых строк (предотвращая вызов от мутации строки из-под вас).
(3) снова с производительностью; вы проверяете равенство, но затем используете авторелиз. Это влечет за собой ненужные накладные расходы.
(4) * все они кажутся намного медленнее во время выполнения* указывает на то, что вы на самом деле не пробовали его, не выявили проблемы с производительностью и преждевременно оптимизируете свой код. Учитывая (1) и (3), вероятно, гораздо легче решить проблемы производительности.
Мои предложения:
(1) Используйте @synthesize. Он будет генерировать правильный и быстрый код, адресуя (1) и (3).
(2) Используйте кво или один из других механизмов. Пока вы не определите проблему производительности с помощью инструментария и количественной оценки, у вас не будет проблемы производительности.
(3) рассмотрите возможность использования CoreData (если, конечно, вы не нацелены на OS 2.икс). Пример кода взят из чего-то, что, очевидно, является объектом модели. Если ваш код хорошо интегрирован в модель / представление / контроллер, использование CoreData на уровне модели может упростить ваше приложение, и CoreData делает замечательная работа по отслеживанию изменений.
Нет.
То, чего вы хотите достичь, возможно только глубоко копаясь в Objective-C runtime или используя прокси-объекты.
Почему бы тебе еще раз не взглянуть на кво?
Если вы пишете свой собственный метод доступа(ы) @synthesize уважает это. @синтезировать отдает предпочтение аксессоры вы пишите по своему усмотрению. Просто укажите нужный вам способ доступа, и @synthesize будет проигнорирован. Например, можно реализовать метод доступа, который создает свойство только в том случае, если его еще нет.
Пример:
Здесь" сеттер "синтезируется, а" геттер " - нет.@synthesize standardUserDefaults; - (NSUserDefaults *)standardUserDefaults { NSLog(@"standardUserDefaults"); if (!standardUserDefaults) { NSLog(@"standardUserDefaults new"); self.standardUserDefaults = [NSUserDefaults standardUserDefaults]; } return standardUserDefaults; }