就好奇而言,UIView类的nextResponder方法实现如何知道谁是管理视图的UIViewController? UIResponder文档说明了这一点,我可以看到它有效,但我不太明白。据我所知,UIView没有保持对它的控制器的引用,那么幕后发生了什么?或者我只是遗漏了一些明显的东西?
我对Objective-C和iPhone开发还很新,所以如果这很明显,我很抱歉,但我很好奇。
谢谢!
答案 0 :(得分:8)
responder chain与视图层次结构分开。响应者链可能如下所示:
First Responder > View Hierarchy > Window > Window Delegate > etc...
但是,对象可以将自己插入到响应程序链中,这就是UIViewController的作用。来自文档:
由于视图控制器与它们管理的视图紧密绑定,因此它们也是用于处理事件的响应程序链的一部分。视图控制器本身是UIResponder类的后代,并插入到托管视图及其超级视图之间的响应链中。
在Big Cocoa中,这是使用-setNextResponder:方法完成的。这种方法在Cocoa Touch中并不公开,但是UIViewController似乎也是如此。
答案 1 :(得分:2)
如果查看UIView.h,可以看到名为_viewDelegate的成员变量,其类型为UIViewController *,这可能是在设置viewcontroller的view属性时存储视图控制器引用的位置,以及它知道的位置当你拨打nextResponder时。
答案 2 :(得分:1)
uiview上实际上有一个私有api来获取它所属的uiviewcontroller。非常便利 ;) 我的猜测是,当视图添加到视图控制器(controller.view)时,此属性已设置。
答案 3 :(得分:0)
我的猜测是系统可能会维护UIViewController对象与其根UIView对象之间的映射。响应者链的遍历代码可以使用此映射将事件传递给相应的UIViewController对象。
通常使用以下内容添加子视图:
subview = [viewController view]
[superview addSubview subview]
addSubview方法自动将superview设置为子视图的下一个响应者,所以:
a)viewController没有机会在superview和subview之间插入自己。
b)viewController不知道superview,因此无法将其设置为下一个响应者。c)Apple建议不要跨控制器共享视图。在没有多线程的情况下,只有存在视图和视图控制器的映射时,此限制才有意义。