如何通过类别实现协议?

时间:2012-05-04 05:24:16

标签: objective-c ios ocmock

如何使用协议的一般实现来装饰类?

对不起可能是一个明显的问题。我是目标c的新手,所以我仍然只是踩着水。

我有一个协议,我想要一个通用的实现:

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

我有几个我想要选择的对象:

@interface Widget : NSObject <SelectableElement>
@end

@interface Duhicky : NSObject <SelectableElement>
@end

我想做的是编写一次协议的实现,并确保两个对象都以这种方式实现。

我认为我不能写一个泛型类并将它绑定到两者,所以我想一种方法是在公共类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

当然,我无法定义一个属性变量来执行此操作,我需要使用关联对象存储...我在这里没有演示过。

这是将可选行为一般性地添加到实现可选元素协议的任何内容的唯一方法吗?还是有一种更明显的方式让我失踪?

我当然可以使用继承来实现这个简单的例子,但这只能用于以这种方式实现单个协议。这种方法我认为是自然适合的,还是黑客攻击?

3 个答案:

答案 0 :(得分:1)

创建一个实现协议的类,即。 SelectableObject然后让WidgetDuhicky类继承SelectableObject。

答案 1 :(得分:0)

听起来你想要像Ruby中的Mixin。不幸的是,这在Objective-C的语言级别上是不可能的。分享行为的唯一方法是通过继承。

那就是说,你可以用Objective-C运行时做一些技巧来实现你想要的。使用您正在使用的语言可能不是一个好主意,但如果您想探索此选项,请查看此处:http://cocoadev.com/wiki/MethodSwizzling

答案 2 :(得分:0)

可悲的是,这是继承特别不适合这个问题的案例之一。

但是,您可以在Cocoa框架(NSResponderUIResponder)中看到此(ab)使用继承。如果您不需要控制继承结构(外部框架中的某个对象),则需要使对象可选,您将遇到问题。

你在NSObject上的类别会起作用,我认为在这种情况下它更可取。乍一看,这些方法对于每个对象来说似乎很苛刻,但由于caching in the method lookup mechanism,性能损失很小。