2

我的 NSDocument 子类实现了 selectAll:。唯一的问题是,我使用的是 NSTableView,它还实现了 selectAll:。但是, NSTableView 中的 selectAll: 操作并没有做我想要的,它确实阻止了我的 Document 类中的 selectAll: 方法在响应者链中被访问。

我已经有一个 NSTableView 的子类,经过一番探索后,我通过向我的 NSTableView 子类添加了一个 respondsToSelector: 方法,告诉它没有 selectAll: 操作,从而使事情按我想要的方式工作:

-(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

4

1 回答 1

1

发送消息会super影响我们使用该方法的哪个实现。它不会改变谁self

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

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

[super respondsToSelector:targetSelector]

发生什么了?运行时会在超类链中查找 的另一个实现respondsToSelector:,最终会找到 NSObject 的原始实现。该实施有什么作用?好吧,我们刚刚回答了这个问题:它开始搜索targetSelectorin的实现[self class]。那仍然是 MyTableView 类!因此,如果您已moveLeft:在 MyTableView 中定义,respondsToSelector:将会找到它并返回 YES moveLeft:,这与您希望和期望的完全一样。

因此,概括地说,这个搜索被扭曲的唯一选择器是搜索selectAll:- 完全符合您的希望和期望。所以我认为你可以放松,相信你所做的不仅是可以接受的和可行的,而且是你最初提出的问题的正常解决方案。

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

于 2013-10-07T13:55:29.677 回答