从子类中删除操作

时间:2013-10-04 21:34:05

标签: objective-c macos responder-chain

我的NSDocument子类实现了selectAll:。唯一的问题是,我正在使用NSTableView,它还实现了selectAll:。但是,NSTableView中的selectAll:action不能满足我的需要,它确实阻止了我的Document类中的selectAll:方法在响应者链中被访问。

我已经有了一个NSTableView的子类,经过一点点的讨论后,我通过在我的NSTableView子类中添加一个respondsToSelector:方法来实现我想要的工作方式,该子类位于运行时,告诉它没有selectAll:action:

-(BOOL)respondsToSelector:(SEL)targetSelector
{
    if (targetSelector == @selector(selectAll:)) {
        return FALSE; // we don't want tableView's implementation of selectAll
    }
    return [super respondsToSelector:targetSelector];
}

这似乎工作正常,允许我的文档子类中的selectAll:方法做它的事情。但这个解决方案让我有点不安。我在这个子类中实现的其他动作方法怎么样?我是否需要手动检查并为每个人返回true?我确实在这个子类中定义了两个动作,moveLeft:和moveRight:,它们似乎有效,即使我没有在respondsToSelector中处理它们:所以我的问题是,我正确地做到了这一点,还是我缺少一些东西?或者也许有一些完全不同的方法来正确地做到这一点?

顺便说一句,我从OmniGroup论坛上的这篇文章中得到了覆盖respondsToSelector的想法:

http://mac-os-x.10953.n7.nabble.com/Removing-an-action-from-a-subclass-td27045.html

1 个答案:

答案 0 :(得分:1)

super发送邮件会影响我们使用的实施方法。它不会改变self是谁。

让我们试着想象一下respondsToSelector:是如何运作的。给定一个选择器mySelector,它可能会反省超类链上的每个类,从[self class]开始,看它是否实际实现 mySelector

现在,假设您的子类名为MyTableView。当MyTableView说

[super respondsToSelector:targetSelector]

会发生什么?运行时将查找超类链以获得respondsToSelector:的另一个实现,并最终找到NSObject的原始实现。这个实现有什么作用?好吧,我们刚回答:它开始在targetSelector中搜索[self class]的实现。那仍然是MyTableView类!因此,如果您在MyTableView中定义了moveLeft:,则respondsToSelector:会找到它并为moveLeft:返回YES,正如您所希望的那样。

因此,为了概括,此搜索已被变态的选择器是搜索selectAll: - 正如您希望和期望的那样。因此,我认为你可以放松并相信你所做的不仅是可以接受的,而且是可行的,而是你原先提出的问题的正常解决方案。

您可能还想查看Apple的 Objective-C运行时编程指南中的消息转发章节。