Действие Target
Несмотря на то, что делегация, привязка и уведомление полезны для обработки определенных форм общения между объектами в программе, они не особенно подходят для самого видимого вида коммуникации. Пользовательский интерфейс типового приложения состоит из многих графических объектов, и возможно наиболее распространенными из этих объектов являются средства управления. Управление является графическим аналогом реального или логического устройства (кнопка, ползунок, флажки, и т.д.); как с реальным управлением, таким как радио-тюнер, Вы используете его для передачи намерения некоторой системе, которой это - часть — т.е. приложение.
Роль управления в пользовательском интерфейсе проста: Это интерпретирует намерение пользователя и сообщает некоторому другому объекту выполнить тот запрос. Когда пользователь действует на управление, скажем, щелкая по нему или нажимая клавишу Return, устройство генерирует необработанное событие. Управление принимает событие (как соответственно упаковано для Какао) и переводит его в инструкцию, которая является определенной для приложения. Однако события собой не дают много информации о намерении пользователя; они просто говорят Вам, что пользователь щелкнул кнопкой мыши или нажал клавишу. Таким образом, некоторый механизм должен быть призван для обеспечения перевода между событием и инструкцией. Этот механизм вызывают целевым действием.
Какао использует механизм целевого действия для коммуникации между управлением и другим объектом. Этот механизм позволяет управление и, в OS X его ячейка или ячейки, для инкапсуляции информации, необходимой для отправки специализированной инструкции в надлежащий объект. Принимающий объект — обычно экземпляр пользовательского класса — вызывают целью. Действие является сообщением, что управление отправляет к цели. Объект, интересующийся пользовательским событием — целью — является тем, передающим значение для него, и это значение обычно отражается на имя, которое это дает действию.
Target
Цель является получателем сообщения действия. Управление или, более часто, его ячейка содержит цель его сообщения действия как выход (см. Выходы). Цель обычно является экземпляром одного из Ваших пользовательских классов, несмотря на то, что это может быть любой объект Какао, класс которого реализует метод соответствующих мер.
Можно также установить целевой выход ячейки или управления в nil
и позвольте целевому объекту быть определенным во время выполнения. Когда цель nil
, объект приложения (NSApplication
или UIApplication
) поиски надлежащего получателя в предписанном порядке:
Это начинается с первого респондента в ключевом окне и следует
nextResponder
соединяет цепочку респондента к объекту окна (NSWindow
илиUIWindow
) довольный представление.Это пробует объект окна и затем делегата объекта окна.
Если главное окно отличается от ключевого окна, оно тогда запускается с первого респондента в главном окне и прокладывает себе путь цепочка респондента главного окна к объекту окна и его делегату.
Затем, объект приложения пытается ответить. Если это не может ответить, это судит своего делегата. Объект приложения и его делегат являются получателями последней инстанции.
Объекты управления не делают (и не должен) сохранять их цели. Однако клиенты средств управления, отправляющих сообщения действия (приложения, обычно), ответственны за обеспечение, что их цели доступны для получения сообщений действия. Чтобы сделать это, им, вероятно, придется сохранить их цели в управляемых средах памяти. Эта предосторожность применяется одинаково к делегатам и источникам данных.
Действие
Действие является сообщением, которое управление отправляет в цель или, с точки зрения цели, метод целевые реализации для ответа на сообщение действия. Управление или — как часто имеет место в AppKit — ячейка управления хранит действие как переменную экземпляра типа SEL
. SEL
тип данных Objective C, используемый для указания подписи сообщения. Сообщение действия должно иметь простую, отличную подпись. Метод, который это вызывает, ничего не возвращает и обычно имеет единственный параметр типа id
. Этот параметр, условно, называют sender
. Вот пример от NSResponder
класс, определяющий много методов действия:
- (void)capitalizeWord:(id)sender; |
Методы действия, объявленные некоторыми классами Какао, могут также иметь эквивалентную подпись:
- (IBAction) deleteRecord:(id)sender; |
В этом случае, IBAction
не определяет тип данных для возвращаемого значения; никакое значение не возвращается. IBAction
спецификатор типа, который Интерфейсный Разработчик замечает во время разработки приложений для синхронизации действий, добавленных программно с ее внутренним списком методов действия, определенных для проекта.
sender
параметр обычно идентифицирует управление, отправляющее сообщение действия (несмотря на то, что это может быть другой объект, которым заменяет фактический отправитель). Идея позади этого подобна обратному адресу на открытке. Цель может запросить отправителя для получения дополнительной информации, если это должно. Если фактический объект отправки заменяет другим объектом как отправителем, необходимо обработать тот объект таким же образом. Например, скажите, что у Вас есть текстовое поле и когда пользователь вводит текст, метод действия nameEntered:
вызывается в цели:
- (void)nameEntered:(id) sender { |
NSString *name = [sender stringValue]; |
if (![name isEqualToString:@""]) { |
NSMutableArray *names = [self nameList]; |
[names addObject:name]; |
[sender setStringValue:@""]; |
} |
} |
Здесь метод ответа извлекает содержание текстового поля, добавляет строку к массиву, кэшируемому как переменная экземпляра, и очищает поле. Другие возможные запросы к отправителю спросили бы NSMatrix
объект для его выбранной строки ([sender selectedRow]
), выяснение NSButton
объект для его состояния ([sender state]
), и выяснение у любой ячейки связалось с управлением для его тега ([[sender cell] tag]
), тег, являющийся числовым идентификатором.
Действие Target в платформе AppKit
Платформа AppKit использует определенную архитектуру и соглашения в реализации целевого действия.
Средства управления, ячейки и пункты меню
Большинство средств управления в AppKit является объектами, наследовавшимися от NSControl
класс. Несмотря на то, что управление несет начальную ответственность за отправку сообщения действия к его цели, это редко переносит информацию, должен был отправить сообщение. Для этого это обычно полагается на свою ячейку или ячейки.
Управление почти всегда имеет одну или более ячеек — объекты, наследовавшиеся от NSCell
— связанный с ним. Почему там эта ассоциация? Управление является «относительно тяжелым» объектом, потому что оно наследовало все объединенные переменные экземпляра своих наследователей, включающих NSView
и NSResponder
классы. Поскольку средства управления являются дорогими, ячейки используются для подразделения экранной недвижимости управления в различные функциональные области. Ячейки являются легкими объектами, которые могут считаться накладывающий все или часть управления. Но это не только подразделение области, это - разделение труда. Ячейки делают часть получения, которое должны были бы иначе сделать средства управления, и ячейки содержат некоторые данные, которые должны были бы иначе перенести средства управления. Два элемента этих данных являются переменными экземпляра для цели и действия. Рисунок 12-1 изображает архитектуру ячейки управления.
Быть абстрактными классами, NSControl
и NSCell
и не полностью обработайте установку цели и переменных экземпляра действия. По умолчанию, NSControl
просто устанавливает информацию в ее связанной ячейке, если Вы существуете. (NSControl
самостоятельно поддержки только непосредственное отображение между собой и ячейкой; подклассы NSControl
такой как NSMatrix
поддерживайте многократные ячейки.) В его реализации по умолчанию, NSCell
просто повышает исключение. Необходимо пойти один шаг вперед вниз цепочка наследования для нахождения класса, действительно реализующего установку цели и действие: NSActionCell
.
Объекты произошли из NSActionCell
обеспечьте цель, и действие оценивает их средствам управления, таким образом, средства управления могут составить и отправить сообщение действия в надлежащий получатель. NSActionCell
возразите мыши дескрипторов (курсор) отслеживание путем выделения его области и помощи его управлению в передающих сообщениях действия к указанной цели. В большинстве случаев, ответственность за NSControl
появлению и поведению объекта полностью предаются соответствие NSActionCell
объект. (NSMatrix
, и его подкласс NSForm
, подклассы NSControl
это не соблюдает это правило.)
Когда пользователи выбирают элемент из меню, действие отправляется в цель. Все же меню (NSMenu
объекты) и их элементы (NSMenuItem
объекты), являются абсолютно отдельными, в архитектурном смысле, от средств управления и ячеек. NSMenuItem
класс реализует механизм целевого действия для своих собственных экземпляров; NSMenuItem
объект имеет и цель и переменные экземпляра действия (и связанные методы доступа) и отправляет сообщение действия в цель, когда пользователь выбирает его.
Ставя цель и действие
Можно поставить цели и действия ячеек и средства управления программно или при помощи Интерфейсного Разработчика. Для большинства разработчиков и большинства ситуаций, Интерфейсный Разработчик является предпочтительным подходом. Когда Вы используете его для установки средств управления и целей, Интерфейсный Разработчик обеспечивает визуальное подтверждение, позволяет Вам блокировать соединения и архивирует соединения с файлом пера. Процедура проста:
Объявите метод действия в заголовочном файле Вашего пользовательского класса, имеющего
IBAction
спецификатор.В Интерфейсном Разработчике соедините управление, отправляющее сообщение в метод действия цели.
Если действие обрабатывается суперклассом Вашего пользовательского класса или стандартным AppKit или классом UIKit, можно сделать соединение, не объявляя метода действия. Конечно, если Вы объявляете метод действия сами, несомненно, необходимо будет реализовать его.
Для установки действия и цели программно используйте следующие методы для отправки сообщений в объект ячейки или управление:
- (void)setTarget:(id)anObject; |
- (void)setAction:(SEL)aSelector; |
Следующий пример показывает, как Вы могли бы использовать эти методы:
[aCell setTarget:myController]; |
[aControl setAction:@selector(deleteRecord:)]; |
[aMenuItem setAction:@selector(showGuides:)]; |
Programmatically, ставящий цель и действие, действительно имеет свои преимущества, и в определенных ситуациях это - единственный возможный подход. Например, Вы могли бы хотеть, чтобы цель или действие варьировались согласно некоторому условию во время выполнения, такой как, существует ли сетевое соединение или было ли загружено окно инспектора. Другой пример - когда Вы динамично заполняете элементы всплывающего меню, и Вы хотите, каждый открывает элемент для имения его собственного действия.
Действия, определенные AppKit
Платформа AppKit не только включает многих NSActionCell
- основанные средства управления для отправки сообщений действия, это определяет методы действия во многих его классах. Некоторые из этих действий подключены к целям по умолчанию при создании проекта приложения Какао. Например, команда Quit в меню приложения подключена с terminate:
метод в глобальном объекте приложения (NSApp
).
NSResponder
класс также определяет много сообщений действия по умолчанию (также известный как стандартные команды) для общих операций на тексте. Это позволяет текстовой системе Какао отправлять эти, действие передает цепочку респондента приложения — иерархическую последовательность объектов обработки событий — где это может быть обработано первым NSView
, NSWindow
, или NSApplication
возразите, что реализует соответствующий метод.
Действие Target в UIKit
Платформа UIKit также объявляет и реализует комплект классов управления; классы управления в этой платформе наследовались от UIControl
класс, определяющий большую часть механизма целевого действия для iOS. Однако, существуют некоторые принципиальные различия в том, как AppKit и платформы UIKit реализуют целевое действие. Одно из этих различий - то, что UIKit не имеет никаких истинных классов ячейки. Средства управления в UIKit не полагаются на свои ячейки для получения информации о действии и цели.
Большее различие в том, как эти две платформы реализуют целевое действие, заключается в природе модели событий. В платформе AppKit пользователь обычно использует мышь и клавиатуру для регистрации событий для обработки системой. Эти события — такие как щелчок по кнопке — ограничиваются и дискретны. Следовательно, объект управления в AppKit обычно распознает единственное физическое явление как триггер для действия, которое это отправляет в его цель. (В случае кнопок это - событие mouseUp.) В iOS пальцы пользователя - то, что порождает события вместо щелчков мышью, мышь перетаскивает, или физические нажатия клавиш. Может быть больше чем один палец, касающийся объекта экрана когда-то, и эти касания могут даже входить в различные направления.
Для учета этой мультисенсорной модели событий UIKit объявляет ряд констант события управления в UIControl.h
это указывает различные физические жесты, которые пользователи могут сделать на средствах управления, таких как то, чтобы шевелить пальцем от управления, перетаскивания пальца в управление и приземление в текстовом поле. Можно сконфигурировать объект управления так, чтобы он реагировал один или больше этих сенсорных событий путем отправки сообщения действия в цель. Многие классы управления в UIKit реализованы для генерации определенных событий управления; например, экземпляры UISlider
класс генерирует a UIControlEventValueChanged
событие управления, которое можно использовать для отправки сообщения действия в целевой объект.
Вы устанавливаете управление так, чтобы оно отправило сообщение действия в целевой объект путем соединения и цели и действия с одним или более событиями управления. Чтобы сделать это, отправить addTarget:action:forControlEvents:
к управлению для каждой пары целевого действия Вы хотите указать. Когда пользователь касается управления определяемым способом, управление передает сообщение действия к глобальной переменной UIApplication
объект в a sendAction:to:from:forEvent:
сообщение. Как в AppKit, глобальный объект приложения является централизованной точкой отгрузки для сообщений действия. Если управление указывает a nil
цель для сообщения действия, приложение запрашивает объекты в цепочке респондента, пока это не находит тот, который готов обработать сообщение действия — т.е. одна реализация метода, соответствующего селектору действия.
В отличие от платформы AppKit, где метод действия может иметь только один или возможно две действительных подписи, платформа UIKit позволяет три различных форм селектора действия:
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event
Для узнавания больше о механизме целевого действия в UIKit считайте Ссылку класса UIControl.