1

你如何用一些通用的协议实现来装饰一个类?

对不起,这可能是一个明显的问题。我是目标 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

当然,我不能定义一个属性变量来做到这一点,我需要使用关联对象存储......我没有在这里演示。

这是将可选行为一般添加到实现可选元素协议的任何东西的唯一方法吗?或者有没有更明显的方式我错过了?

我当然可以使用继承来实现这个简单的示例,但这仅适用于以这种方式实现单个协议。我建议的这种方法是天作之合,还是一种技巧?

4

3 回答 3

1

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

于 2012-05-04T05:31:53.753 回答
0

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

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

于 2012-05-08T09:35:05.753 回答
0

可悲的是,这是继承特别不适合该问题的情况之一。

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

您在 NSObject 上的类别将起作用,在这种情况下我认为它更可取。乍一看,每个对象都携带这些方法似乎很笨拙,但由于方法查找机制中的缓存,性能损失很小。

于 2012-05-08T09:57:03.453 回答