Re: Responder Chain Confusion
Re: Responder Chain Confusion
- Subject: Re: Responder Chain Confusion
- From: John Joyce <email@hidden>
- Date: Mon, 08 Sep 2014 10:18:27 +0900
On 2014/09/08, at 8:49, email@hidden wrote:
>
>
>
>
>>> On 2014/09/08, at 3:16, Kyle Sluder <email@hidden> wrote:
>>>
>>> On Sep 7, 2014, at 9:24 AM, email@hidden wrote:
>>>
>>> Hi all
>>>
>>> I just spent a bit of time poking around the responder chain and nil targeted actions.
>>> I built a view controller and a view hierarchy with controls that should be configurable.
>>> When instantiating the view controller the interface allows configuring the action SEL of the controls. Reuse is the goal of course.
>>> I know 10.10 changes things greatly for view controllers. But on 10.9 that's not there.
>>>
>>> Anyway, I need to insert the view controller into the responder chain between its top level view and that view's superview.
>>> That wasn't too bad. Implement the missing reference to the vc in a view subclass and give the vc a callback when the view is in place.
>>>
>>> But what I found while tinkering is that for non-document based apps from a vanilla project template there was no next responder for the window or the NSApplication instance.
>>> I had a method in the app delegate that I was trying to reach via nil targeted action. It couldn't get there.
>>> So I set the window nextResponder to the app and the app to the app delegate. I also made the app delegate an NSResponder subclass.
>>>
>>> It feels like overkill.
>>> Am I missing something simple?
>>
>> IIRC, the window is not supposed to have a nextResponder. Conceptually, the next responder of a window is its delegate, and the next responder of an application is *its* delegate, but there is no requirement that these objects are instances of subclasses of NSResponder. Therefore the responder chain mechanism manually jumps from the window to its delegate, then to the application, and finally to the app’s delegate. (It also inserts window controllers as well as the shared NSDocumentController instance if one has been created.)
>>
>> If the message never reached your app delegate, I suspect you failed to patch the view controller’s nextResponder in correctly.
>>
>> --Kyle Sluder
>
> I figured as much. It seemed like none of that should be necessary normally. But why would it be able to send standard responder messages like the orderOut: action message to nil and reach the window?
> I must be inserting it wrongly into the responder chain.
>
> The docs describe exactly what everyone said here.
> My app delegate does implement the selector.
> I even exposed it in the header.
> It is an action message.
> So without doing anything special I should be able to send it right up the chain and reach the app delegate.
> The docs even state ( in the Cocoa Event Handling Guide, the others gloss over this) that a window delegate and app delegate do not need to be NSResponder descendants.
>
> I will look at this with an even simpler test app and see what's going on.
>
> I think you're right that I borked the responder chain insertion.
> Without inserting the controller into the responder chain, should the view follow the normal behavior of having its superview has nextResponder?
>
Ok, I re-read the docs.
I found the solution I needed, without inserting anything into the responder chain.
I was doing this, and that was why I felt I needed to insert the vc into the responder chain. I even set the vc’s nextResponder to the window, which should have shortened the trip slightly, but the action message stopped at the window. (the self.negativeResponseAction is a configurable SEL property on the vc, the method call is in the vc’s action method of the control inside the vc’s view hierarchy)
BOOL performed = [sender tryToPerform:self.negativeResponseAction with:sender];
For what I want to do, vend a view with some controls whose actions are configurable, the approach that works gracefully is this:
BOOL performed = [[NSApplication sharedApplication] sendAction:self.negativeResponseAction to:nil from:sender];
In true Cocoa fashion, if it is taking a lot of effort and many lines of code, we are probably doing something wrong and there is probably a short simple solution, even if it isn’t immediately obvious.
The second method is clearly and explicitly documented to do things the way the Event Handling Guide says the responder chain should work for actions.
The first method is a lot less less documented and makes no assurances in the NSResponder docs about what it will or will not do beyond sending to the nextResponder. (one would think that should be fine from the docs, but the second method is clearly documented to do the right thing and it works well for nil-targeted action)
For whatever reason, tryToPerform:with: does not work to forward message up the chain.
Sending sendAction:to:from: to the NSApp works like a charm.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden