views:

788

answers:

3

Just as a matter of curiosity, how does the nextResponder method implementation of the UIView class know who is the UIViewController that manages the view? The UIResponder documentation states this, and I can see it work, but I don't quite understand it. To the best of my knowledge, a UIView does not maintain a reference to it's controller, so what's happening behind the scenes? Or am I just missing something obvious?

I'm still very new to Objective-C and iPhone development so I apologize if this is something obvious, but I am quite curious.

Thanks!

+2  A: 

The responder chain is separate from the view hierarchy. The responder chain might look like this:

First Responder > View Hierarchy > Window > Window Delegate > etc...

However, objects can insert themselves into the responder chain and that's what UIViewController does. From the docs:

Because view controllers are tightly bound to the views they manage, they are also part of the responder chain used to handle events. View controllers are themselves descendants of the UIResponder class and are inserted into the responder chain between the managed view and its superview.

In Big Cocoa, this is accomplished using the -setNextResponder: method. That method isn't public in Cocoa Touch, but nevertheless that's what UIViewController appears to do.

Darren
A: 

My guess is that the system may maintain a mapping between UIViewController objects and their root UIView objects. The code for traversal of responder chain may use this mapping to pass the event to the corresponding UIViewController object.

Typically subviews are added using:

subview = [viewController view]

[superview addSubview subview]

addSubview method automatically sets superview as the next responder for subview, so:

a) viewController wont have the opportunity to insert itself between superview and subview.

b) viewController does not know about superview, hence it cannot set it as its next responder.

c) Apple recommends that a view may not be shared across controllers. In absence of multi-threading this restriction makes sense only if there is a map of views and view controllers.

Shivaraj Tenginakai
A: 

I would also like to know this. None of the answers above actually answer the original question.

In Cocoa Touch the UIResponder does not store the nextResponder, and UIView does not keep a reference to its view controller.

From UIResponder class reference:

The UIResponder class does not store or set the next responder automatically, instead returning nil by default. Subclasses must override this method to set the next responder. UIView implements this method by returning the UIViewController object that manages it (if it has one) or its superview (if it doesn’t);

So how is UIView nextResponder method implemented? Where is the reference to its view controller stored?

I believe a mapping is kept somewhere between the views and their UIViewControllers. UIWindow has a _windowController iVar that seems rather suspicious :P.

Anyhow.. I'm just guessing.

pfandrade