Поскольку я не могу создать синтезированное свойство в категории в Objective-C, я не знаю, как оптимизировать следующий код:
@interface MyClass (Variant)
@property (nonatomic, strong) NSString *test;
@end
@implementation MyClass (Variant)
@dynamic test;
- (NSString *)test {
NSString *res;
//do a lot of stuff
return res;
}
@end
Тест-метод вызывается несколько раз во время выполнения , и я делаю много вещей , чтобы вычислить результат. Обычно, используя синтезированное свойство, я сохраняю значение в IVar _test при первом вызове метода и просто возвращаю этот IVar в следующий раз. Как я могу оптимизировать приведенный выше код?
Ответы:
Метод @lorean будет работать (примечание: ответ теперь удален) , но у вас будет только один слот для хранения. Поэтому, если вы хотите использовать это в нескольких экземплярах и каждый экземпляр вычисляет отдельное значение, это не сработает.
К счастью, в среде выполнения Objective-C есть такая штука, называемая Associated Objects, которая может делать именно то, что вы хотите:
источник
@selector(test)
в качестве ключа, как описано здесь: stackoverflow.com/questions/16020918/….h-файл
.m-файл
Как обычное свойство - доступно через точечную нотацию
Более простой синтаксис
В качестве альтернативы вы можете использовать
@selector(nameOfGetter)
вместо создания ключа статического указателя, например:Подробнее см. Https://stackoverflow.com/a/16020927/202451.
источник
@dynamic objectTag;
.@dynamic
означает, что сеттер и геттер будут сгенерированы где-то еще, но в этом случае они реализованы прямо здесь.Данный ответ отлично работает, и мое предложение - это просто его расширение, позволяющее избежать написания слишком большого количества шаблонного кода.
Чтобы избежать многократного написания методов получения и установки для свойств категории, в этом ответе представлены макросы. Кроме того, эти макросы упрощают использование свойств примитивных типов, таких как
int
илиBOOL
.Традиционный подход без макросов
Традиционно вы определяете свойство категории, например
Затем вам нужно реализовать метод получения и установки, используя связанный объект и селектор получения в качестве ключа ( см. Исходный ответ ):
Предлагаемый мной подход
Теперь, используя макрос, вы вместо этого напишите:
Макросы определены следующим образом:
Макрос
CATEGORY_PROPERTY_GET_SET
добавляет геттер и сеттер для данного свойства. Только для чтения или только для записи свойства будет использоватьCATEGORY_PROPERTY_GET
иCATEGORY_PROPERTY_SET
макро соответственно.Примитивные типы требуют немного большего внимания
Поскольку примитивные типы не являются объектами, указанные выше макросы содержат пример использования
unsigned int
в качестве типа свойства. Это делается путем обертывания целочисленного значения вNSNumber
объект. Таким образом, его использование аналогично предыдущему примеру:После этой модели, вы можете просто добавить больше макросов также поддержку
signed int
,BOOL
и т.д. ...Ограничения
OBJC_ASSOCIATION_RETAIN_NONATOMIC
По умолчанию используются все макросы .IDE, такие как App Code , в настоящее время не распознают имя установщика при рефакторинге имени свойства. Вам нужно будет переименовать его самостоятельно.
источник
#import <objc/runtime.h>
в противном случае не забудьте добавить в категорию .m файл. Ошибка времени компиляции: неявное объявление функции objc_getAssociatedObject недопустимо в C99 . stackoverflow.com/questions/9408934/…Просто используйте библиотеку libextobjc :
ч-файл:
м-файл:
Подробнее о @synthesizeAssociation
источник
Протестировано только с iOS 9 Пример: добавление свойства UIView в UINavigationBar (Категория)
UINavigationBar + helper.h
UINavigationBar + Helper.m
источник
Другое возможное решение, возможно, более простое, которое не используется,
Associated Objects
- объявить переменную в файле реализации категории следующим образом:Обратной стороной такой реализации является то, что объект функционирует не как переменная экземпляра, а как переменная класса. Кроме того, атрибуты свойств не могут быть назначены (например, используемые в связанных объектах, таких как OBJC_ASSOCIATION_RETAIN_NONATOMIC)
источник