2012-05-04 2 views
1

Как вы украшаете класс некоторой общей реализацией протокола?Как реализовать протокол в целом с категорией?

Извините, что может быть очевидным вопросом. Я новичок в объективе c, и я все еще немного пошатываю воду.

У меня есть протокол, который я хочу родовое реализацию:

@protocol SelectableElement <NSObject> 
@property BOOL selected; 
@end 

у меня есть несколько объектов, которые я хочу быть выбор:

@interface Widget : NSObject <SelectableElement> 
@end 

@interface Duhicky : NSObject <SelectableElement> 
@end 

Что я d хотел бы сделать, это написать реализацию протокола один раз и убедиться, что оба объекта реализуют его таким образом.

Я не думаю, что я могу написать общую категорию и привязать его к обоим, так что я думаю, один из способов сделать это, чтобы добавить реализовать категорию на общий класс NSObject:

@implementation NSObject (Selectable) 
- (BOOL)selectable 
{ 
    if (![self conformsToProtocol:@protocol(SelectableElement)]) return; 

    return YES; // Use associative storage for this? 
} 

- (void)setSelectable:(BOOL)selectable 
{ 
    if (![self conformsToProtocol:@protocol(SelectableElement)]) return; 

    // set this associatively? 
} 
@end 

Из Конечно, я не могу определить переменную свойства, чтобы сделать это, мне нужно было бы использовать ассоциативное хранилище объектов ... которое я здесь не продемонстрировал.

Является ли это единственным способом добавления выборочного поведения в общем случае ко всему, что реализует протокол выбираемого элемента? Или есть более очевидный способ, который мне не хватает?

Я могу, конечно, использовать наследование для реализации этого простого примера, но это будет работать только для реализации одного протокола таким образом. Является ли этот подход, который, как я предложил, считается естественным, или это взлом?

Joe

ответ

1

Создайте класс, который реализует протокол, т.е. SelectableObject, а затем введите Widget и Duhicky классы inherit SelectableObject.

+0

+1: Или иначе, классы Виджета и Духики должны быть подклассами SelectableObject. – lnafziger

0

Кажется, вы хотите что-то вроде Mixin в Ruby. К сожалению, это невозможно на уровне языка в Objective-C. Единственный способ поделиться своим поведением - это наследование.

При этом вы можете сделать некоторые трюки с помощью среды выполнения Objective-C, чтобы достичь желаемого. Вероятно, не рекомендуется работать против используемого вами языка, но если вы хотите изучить этот вариант, посмотрите здесь: http://cocoadev.com/wiki/MethodSwizzling

0

К сожалению, это один из тех случаев, когда наследование особенно плохо подходит для проблема.

Однако вы можете увидеть это (ab) использование наследования в каркасах Какао (NSResponder или UIResponder). Вы столкнетесь с проблемами, если вам нужно сделать выбор объекта, если вы не контролируете структуру наследования (какой-то объект во внешней структуре).

Ваша категория в NSObject будет работать, и я бы счел это предпочтительным в этом случае. На первый взгляд кажется, что для каждого объекта небезопасно использовать эти методы, но штраф за производительность невелик из-за caching in the method lookup mechanism.

Смежные вопросы