質問

My NSDocument subclass implements selectAll:. Only problem is, I'm using NSTableView, and it also implements selectAll:. However, the selectAll: action in NSTableView doesn't do what I want, and it does prevent the selectAll: method in my Document class from ever being reached in the responder chain.

I already have a subclass of NSTableView, and after poking around a bit I got things working the way I want by adding a respondsToSelector: method to my NSTableView subclass which lies to the runtime by telling it there is no 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];
}

This seems to work fine, allowing the selectAll: method in my document subclass to do its thing. But this solution leaves me a bit uneasy. What about other action methods I have implemented in this subclass? Do I need to manually check and return true for each of them? I do have two actions defined in this subclass, moveLeft: and moveRight:, and they seem to work, even though I am not handling them in respondsToSelector:. So my question is, am I doing this correctly, or is there something I am missing? Or perhaps there is some entirely different way to do this properly?

By the way, I got the idea of overriding respondsToSelector from this post on the OmniGroup forum:

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

役に立ちましたか?

解決

Sending a message to super affects which implementation of that method we use. It doesn't change who self is.

So let's try to imagine how respondsToSelector: works. Given a selector mySelector, it probably introspects every class up the superclass chain, starting with [self class], to see whether it actually implements mySelector.

Now then, let's say your subclass is called MyTableView. When MyTableView says

[super respondsToSelector:targetSelector]

what happens? The runtime will look up the superclass chain for another implementation of respondsToSelector:, and eventually will find NSObject's original implementation. What does that implementation do? Well, we just answered that: it starts the search for an implementation of targetSelector in [self class]. That's still the MyTableView class! So if you have defined moveLeft: in MyTableView, respondsToSelector: will find it and will return YES for moveLeft:, exactly as you hope and expect.

Thus, to generalize, the only selector for which this search has been perverted is the search for selectAll: - exactly as you hope and expect. So I think you can relax and believe that what you're doing is not only acceptable and workable but the normal solution to the problem you originally posed.

You might also like to look at the Message Forwarding chapter of Apple's Objective-C Runtime Programming Guide.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top