Главная » iPhone, Objective-C, Программирование для iOS и MacOS » Модель  «приемник/действие» Objective-C

0

В частности, механизм «приемник/действие. используется таймерами. При создании таймера указывается задержка, приемник и действие. После истечения заданной задержки таймер отправляет сообщение действия своему приемнику.

Мы создадим программу с циклом событий и таймером. Каждые две секунды таймер будет отправлять своему приемнику сообщение действия. Мы создадим класс, экземпляр которого и будет использоваться в качестве приемника.

Рис. 24.1. Logger является приемником для NSТimer

Создайте в Xcode новый проект: программу командной строки Foundation с именем Callbacks. Начнем с простого создания работоспособного цикла событий. Внесите изменения в main.m:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])

{

@autoreleasepool {

[[NSRunLoop currentRunLoop] run];

}

return 0;

}

Постройте и запустите программу. Обратите внимание: метод run никогда не возвращает управление. Он выполняется в бесконечном цикле, ожидая, пока что- нибудь произойдет. Чтобы его прервать, необходимо завершить программу. (Выберите команду Product → Stop.)

Теперь мы создадим класс, который будет использоваться в качестве приемника таймера. Создайте новый файл: класс Objective-C с именем Logger, который является субклассом NSObject. (Шаблон класса вызывается командой File→New→NewFile…) В файле Logger.h объявите метод действия:

#import <Foundation/Foundation.h>

@interface Logger : NSObject

-­‐    (void)sayOuch:(NSTimer  *)t;

@end

Метод действия получает один аргумент – объект, отправляющий сообщение действия. В нашем случае это объект таймера.

Реализуйте в Logger.m простой метод sayOuch::

#import "Logger.h"

@implementation Logger

-­‐   (void)sayOuch:(NSTimer  *)t

{

}

@end

NSLog(@"Ouch!");

Рис. 24.2. Поиск метода с указанным именем

На этой стадии необходимо слегка отвлечься и поговорить о селекторах. Вспомните, что при отправке сообщения объекту класс объекта проверяет, содержит ли он метод с указаным именем. Поиск переходит вверх по цепочке наследования, пока какой-либо класс не ответит: «Да,у меня есть метод с таким именем».

Естественно, такая проверка должна выполняться очень, очень быстро. При использовании фактического имени метода (которое может быть очень длинным) поиск будет относительно медленным. Для ускорения проверки компилятор присваивает каждому имени метода в  программе уникальный идентификатор. На стадии выполнения вместо имени метода используется его идентификатор.

Уникальное число, представляющее конкретное имя метода, называется селектором. Чтобы создать таймер, отправляющий сообщение sayOuch: классу Logger, необходимо приказать компилятору определить его селектор. Для решения этой задачи используется директива компилятора @sеlесtоr.

В  файле  main.m  создайте  экземпляр  Logger и  сделайте  его  приемником

NSTimer. В качестве действия укажите селектор sayOuch:.

Рис. 24.3. Что происходит в действительности

#import <Foundation/Foundation.h>

#import "Logger.h"

int main (int argc, const char * argv[])

{

@autoreleasepool {

Logger *logger = [[Logger alloc] init];

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0

target:logger

selector:@selector(sayOuch:)

[[NSRunLoop currentRunLoop] run];

userInfo:nil repeats:YES];

}

return 0;

}

Постройте и запустите программу. (Компилятор выдает сообщение о не используемой переменной, пока не обращайте на него внимания.) Сообщение Ouch! должно выводиться на консоль каждые две секунды.

Обратите    внимание:    двоеточие    является    частью    селектора.    Запись

@selector(sayOuch) не эквивалентна @sеlесtоr(sауОuсh:).

А теперь снова взгляните на предупреждение компилятора. Фактически он говорит: «Вы создали переменную timer, но не используете ее». В некоторых ситуациях (таких, как эта) для подавления предупреждений необходимо пометить переменную и указать, что она не используется намеренно. Для этой цели используется модификатор _unused. Добавьте следующий фрагмент.

    unused NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0

target:logger selector:@selector(sayOuch:) userInfo:nil

repeats:YES];

Постройте программу снова. На этот раз предупреждение исчезает.

Источник: Аарон Хилегас, «Objective-C. Программирование для iOS и MacOS», 2012 г.

По теме:

  • Комментарии