Могу ли я переопределить работу @synthesize в Objective C? - PullRequest
5 голосов
/ 16 сентября 2009

Я создаю базовый класс с флагом 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 ]

8 голосов
/ 16 сентября 2009

Несколько вопросов здесь:

(1) Если вы беспокоитесь о производительности сеттера, вам не следует использовать -isEqualToString: в вашем сеттере. Вместо этого сделайте сравнение указателя, потому что это все, что имеет значение в этом контексте.

(2) Если у вас есть атрибут NSString, вы должны копировать на множестве. Копия бесплатна для неизменных строк и сохранит ваш бекон для изменяемых строк (предотвращая изменение строки вызывающей стороной из-под вас).

(3) Опять с производительностью; Вы проверили на равенство, но затем используйте авто-релиз. Это влечет за собой ненужные накладные расходы.

(4) * все они кажутся намного медленнее во время выполнения * указывает на то, что вы на самом деле не пробовали это, не определили проблему с производительностью и преждевременно оптимизируете свой код. Учитывая (1) и (3), вероятно, гораздо проще решать проблемы с производительностью.

Мои предложения:

(1) Используйте @synthesize. Будет сгенерирован правильный и быстрый код с адресами (1) и (3).

(2) Используйте КВО или один из других механизмов. Пока вы не обнаружите проблему с производительностью с помощью инструментов и количественного анализа, у вас не будет проблем с производительностью.

(3) Рассмотрите возможность использования CoreData (если, конечно, вы не нацелены на OS 2.x). Пример кода взят из чего-то, что, очевидно, является модельным объектом. Если ваш код хорошо интегрирован в модель / представление / контроллер, использование CoreData на уровне модели может упростить ваше приложение, а CoreData прекрасно справляется с отслеживанием изменений.

7 голосов
/ 16 сентября 2009

Я не знаю, как это позволяет вам переопределить то, что делает @synthesize.

В конце концов, он используется для создания основных методов доступа - т.е. те, которые не имеют определенного поведения.

Может быть, вам стоит взглянуть на кодирование значения ключа и наблюдение значения ключа?

3 голосов
/ 16 сентября 2009

Нет.

То, чего вы хотите достичь, возможно, только углубившись в Objective-C runtime или используя прокси-объекты .

Почему бы тебе снова не взглянуть на КВО?

1 голос
/ 22 сентября 2011

Если вы пишете свои собственные методы доступа, @synthesize это учитывает. @synthesize отдает приоритет принадлежностям, которые вы пишете самостоятельно. Просто предоставьте понравившийся вам аксессор, и @synthesize будет игнорироваться. Например, вы можете реализовать метод доступа, который создает свойство только в том случае, если его там еще нет.

Пример:

@synthesize standardUserDefaults;

- (NSUserDefaults *)standardUserDefaults {
    NSLog(@"standardUserDefaults");
    if (!standardUserDefaults) {
        NSLog(@"standardUserDefaults new");
        self.standardUserDefaults = [NSUserDefaults standardUserDefaults];
    }
    return standardUserDefaults;
}

Здесь «сеттер» синтезируется, а «геттер» - нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...