Как стать автором
Обновить

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

Я сейчас предложу еретическое, по общему мнению, решение, но препроцессор в ObjC делает тоже самое

В частности, вы можете заменить +(BOOL)resolveMethodFor:(id)target selector:(SEL)sel на вызов препроцессорной директивы.
Плюсы такого решения:


  • нет оверхеда на использование рантайма
  • директива может быть составлена так, чтобы ошибки в именах методов проверялись во время компиляции

Вы предлагаете написать #define generate_accessor(property_name) ... и добавлять его для каждого поля?


Решение рабочее, но:


  • нужно будет проделать чуть больше действий для добавления нового поля
  • подсветка синтаксиса при составлении и редактировании макросов осутствует

Оверхедом при использовании рантайма можно пренебречь, так как resolveMethodFor:selector: вызывается только при первом обращении к полю. Ошибки в именах методов в решении с рантаймом не возникают так как селектор передаётся в аргументе.

Не сильно больше: вы можете определить что-нибудь типа


#define PROPERTY_DEF(type, name) <...>
#define PROPERTY_IMP(type, name) <...>

И использовать как


@interface Storage : NSObject 

PROPERTY_DEF((NSString*), prop1)
PROPERTY_DEF((NSString*), prop2)

@end

@implementation Storage 

PROPERTY_IMP((NSString*), prop1)
PROPERTY_IMP((NSString*), prop2)

@end

В качестве обхода проблемы с подсветкой синтаксиса я обычно реализовывал один экземпляр свойства "в коде", а потом переделывал его в препроцессорную директиву. Так же у XCode есть инструмент для просмотра результата работы препроцессора — там подсветка синтаксиса работает корректно.

В реализации PROPERTY_IMP придётся на макросах приводить propertyName к setPropertyName, что не очень приятно. Зато в вашем решении проще поддержать скалярные типы.


А зачем макрос PROPERTY_DEF? Разве в нём не будет @property (attributes) type name?

Да, по поводу PROPERTY_IMP вы правы, в С'шном препроцессоре нет нативного способа сделать upper case. Когда я использовал что-то подобное, я передавал два параметра для имени, PROPERTY_IMP(type, camelName, CapsName). Без PROPERTY_DEF в данном случае можно обойтись, хотя он тут скорее для однообразия.

Извините за грубость и за несанкционированное использование машины времени, но разве IDE в ваше время (Кстати, который год?) не способно автоматически генерировать такой тривиальный код из, ну, не знаю, списка полей класса?
Вы когда-нибудь писали адаптеры для Keychain или NSUserDefaults?

Предлагаю это не делать вообще…

Зарегистрируйтесь на Хабре, чтобы оставить комментарий