Единственное приятное обсуждение, которое я знаю, это запись в блоге Майка Эша . На самом деле это не так сложно.
Мне когда-то нужно было разделить большой подкласс NSManagedObject
на два, но я решил оставить этот факт в деталях реализации, чтобы мне не приходилось переписывать другие части моего приложения. Итак, мне нужно было синтезировать геттер и сеттер, который автоматически отправляет [self foo]
в [self.data foo]
.
Для этого я сделал следующее:
Подготовьте новый метод, уже в моем классе.
- (id)_getter_
{
return objc_msgSend(self.data, _cmd);
}
- (void)_setter_:(id)value
{
objc_msgSend(self.data, _cmd,value);
}
Обратите внимание, что в _cmd
есть селектор. Таким образом, обычно _cmd
является либо @selector(_getter_)
, либо @selector(_setter_)
в этих методах, но я собираюсь включить реализацию _getter_
как реализацию foo
. Затем _cmd
содержит @selector(foo)
и, таким образом, вызывает self.data
s foo
.
Напишите общий метод синтеза:
+(void)synthesizeForwarder:(NSString*)getterName
{
NSString*setterName=[NSString stringWithFormat:@"set%@%@:",
[[getterName substringToIndex:1] uppercaseString],[getterName substringFromIndex:1]];
Method getter=class_getInstanceMethod(self, @selector(_getter_));
class_addMethod(self, NSSelectorFromString(getterName),
method_getImplementation(getter), method_getTypeEncoding(getter));
Method setter=class_getInstanceMethod(self, @selector(_setter_:));
class_addMethod(self, NSSelectorFromString(setterName),
method_getImplementation(setter), method_getTypeEncoding(setter));
}
Обратите внимание, что это метод класса. Таким образом, self
обозначает класс. Также обратите внимание, что я не жестко кодировал типы кодов (которые сообщают среде выполнения Objective C, каковы аргументы конкретного метода). Синтаксис кодирования типов задокументирован, но создание вручную очень подвержено ошибкам; Я потратил впустую несколько дней, пока Майк Эш не сказал мне прекратить это. Сгенерируйте его, используя существующий метод.
Создание форвардеров в кратчайшие сроки:
+(void)load
{
for(NSString*selectorName in [NSArray arrayWithObjects:@"foo", @"bar", @"baz",nil]){
[self synthesizeForwarder:selectorName];
}
}
Генерирует foo
, setFoo:
, bar
, setBar:
и baz
, setBaz:
.
Надеюсь, это поможет!