Как UIView nextResponder знает, что такое UIViewController?
Как любопытство, как реализуется реализация метода nextResponder класса UIView, кто является UIViewController, который управляет представлением?
Документация UIResponder утверждает это, и я вижу, что это работает, но я не совсем понимаю. Насколько я знаю, UIView не поддерживает ссылку на контроллер, так что происходит за кулисами? Или я просто пропущу что-то очевидное?
Я все еще очень новичок в разработке Objective-C и iPhone, поэтому прошу прощения, если это что-то очевидное, но мне очень любопытно.
Спасибо!
Ответы
Ответ 1
цепочка ответчиков отделена от иерархии представлений. Цепочка ответчика может выглядеть так:
First Responder > View Hierarchy > Window > Window Delegate > etc...
Однако объекты могут вставляться в цепочку ответчиков и что делает UIViewController. Из документов:
Поскольку контроллеры представлений тесно связаны с представлениями, которыми они управляют, они также являются частью цепи ответчиков, используемой для обработки событий. Контроллеры просмотра сами являются потомками класса UIResponder и вставляются в цепочку ответчиков между управляемым представлением и его супервидом.
В Big Cocoa это выполняется с помощью метода -setNextResponder:. Этот метод не является общедоступным в Cocoa Touch, но тем не менее, что делает UIViewController.
Ответ 2
Если вы посмотрите на UIView.h, вы можете увидеть переменную-член с именем _viewDelegate, которая имеет тип UIViewController *, вероятно, там, где ссылка на диспетчер представлений хранится, когда установлено свойство представления viewcontroller, и где он знает, чтобы посмотреть когда вы вызываете nextResponder.
Ответ 3
на самом деле есть приватный api на uiview, чтобы получить uiviewcontroller, к которому он принадлежит. Очень удобно;)
Я предполагаю, что когда представление добавлено в контроллер вида (controller.view), это свойство установлено.
Ответ 4
Я предполагаю, что система может поддерживать сопоставление между объектами UIViewController и их корневыми объектами UIView. Код для обхода цепочки ответчиков может использовать это сопоставление для передачи события соответствующему объекту UIViewController.
Как правило, подпункты добавляются с помощью:
subview = [viewController view]
[супервизор addSubview subview]
Метод addSubview автоматически устанавливает супервизор в качестве следующего ответчика для subview, поэтому:
a) viewController не будет иметь возможность вставлять себя между супервидом и подвью.
b) viewController не знает о супервизии, поэтому он не может установить его как своего следующего ответчика.
c) Apple рекомендует, чтобы представление не могло использоваться совместно для контроллеров. В отсутствие многопоточности это ограничение имеет смысл только в том случае, если имеется карта представлений и контроллеров представлений.