3

我知道我可以使用类别扩展一个类(例如框架类),但是是否可以让一个您不控制其源代码的类实现您的自定义协议之一?我不仅希望它在发送到实例时响应某些消息,而且理想情况下,希望该类的对象在查询协议时在运行时类型检查时返回 true。

4

2 回答 2

8

您可以定义一个符合协议的类别,因此您可以执行以下操作:

@interface UIWebView (MyGreatExtensions) <UITableViewDelegate>
@end

@implementation UIWebView (MyGreatExtensions)

- (CGFloat)tableView: (UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath {
  return 42.0;
}

// ...

@end

需要考虑的一个小边缘情况是,如果其他人尝试做同样的事情(例如,第三方框架也通过类别添加协议),那么您不能保证您的版本会被使用(当然也不能他们)。

Mark Dalrymple提供了更多关于这种方法的信息。

于 2012-04-27T09:01:16.857 回答
2

我认为这是可能的。您可以通过覆盖 NSObject 的 forwardInvocation: 方法轻松地在 Objective-C 中创建动态代理(这就是 NSUndoManager 的魔力),拦截协议实现者将响应的所有无法识别的消息。我自己从来没有这样做过,所以可能有一种更优雅的方式来做到这一点。

另外,为了让运行时检查同意你的对象确实实现了协议,你可以重写 NSObject 的类方法conformsToProtocol: 像这样:

+ (BOOL)conformsToProtocol:(Protocol *)aProtocol {
    if (aProtocol == @protocol(MyDynamicallyImplementedProtocol))
        return YES;
    return [super conformsToProtocol:aProtocol];
}

您可能需要覆盖更多方法,例如 NSObject 的 instancesRespondToSelector: 和 resolve*: 方法。检查 NSObject类参考以了解更多信息。

于 2012-04-27T08:54:33.310 回答