Как 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 рекомендует, чтобы представление не могло использоваться совместно для контроллеров. В отсутствие многопоточности это ограничение имеет смысл только в том случае, если имеется карта представлений и контроллеров представлений.