ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C Часть 1

Таймер (NSTimer)

Иногда возникает ситуация, когда нужно выполнить каое-то действие несколько раз, но с определнным интервалом. К примеру, вы захотите сделать чтобы ваша программа каждые 5 минут посылала запрос на сервер, чтобы получить новые данные. Для реализации таких задач в Objective-C существует специальный класс NSTimer. Я предлагаю по-ближе познакомиться с этим классом на примере конкретного проекта. Создадим такой проект на основе представления (View-based Application) и назовем его MyTimer.

Теперь изменим класс MyTimerViewController:

MyTimerViewController.h

<code data-result="[object Object]">#import &lt;UIKit/UIKit.h&gt;

@interface MyTimerViewController : UIViewController {
    NSTimer *myTimer;
}

@property (nonatomic, retain) NSTimer *myTimer;

- (IBAction)startTimer;
- (IBAction)stopTimer;

@end</code>

Я добавил в интерфейс переменную, которая и будет нашим таймером, прописал для нее свойства, а так же добавил два метода. Она будут запускать и останавливать таймер.

MyTimerViewController.m

<code data-result="[object Object]">#import "MyTimerViewController.h"

@implementation MyTimerViewController

@synthesize myTimer;

- (void)dealloc {
    if ([myTimer isValid]) {
        [myTimer invalidate];
    }
    self.myTimer = nil;

    [super dealloc];
}

- (IBAction)startTimer {
    self.myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f 
                                                    target:self 
                                                  selector:@selector(tick) 
                                                  userInfo:nil 
                                                   repeats:YES];
}

- (IBAction)stopTimer {
    if ([myTimer isValid]) {
        [myTimer invalidate];
    }
}

- (void)tick {
    NSLog(@"Time tick");
}

@end</code>

В метод startTimer мы создаем таймер с использованием метода scheduledTimerWithTimeInterval. Этот метод принимает пять значений. Рассмотрим каждое из них по порядку.

TimeInterval — периодичность с которой будет вызываться метод таймера;

target — объект класса, в котором находится метод, вызываемый таймером (что-то на подобие делегата);

selector — сам метод, который будет вызываться (точнее с имени метода мы создаем селектор и передаем в качестве параметра);

userInfo — дополнительная информация которую мы хотим передать в метод таймера;

repeats — здесь мы указываем будет вызван таймер один раз или он будет повторятся постоянно

В методе stopTimer мы проверяем работает ли таймер и если работает — останавливаем его. Метод tick и является тем методом, который мы указали при создании таймера. Он вызывается таймером с периодичностью в 1 секунду и выводит в консоль строку Time tick.

Особое внимание следует обратить на то как правильно уничтожать созданный таймер. В первую очередь нужно проверять активен он или нет. Дело в том, что если таймер активен — его не получится удалить. Он все равно будет выполнятся и вызвать свой метод. Это повлечет за собой создание в проекте утечки памяти. Поэтому так же как и в методе stopTimer, мы останавливаем его и только потом удаляем.

Для полной функциональности кода добавьте в *.xib-файл две кнопки и свяжите нажатие на эти кнопки с вызовом методов описаных в интерфейсе.

Таймер можно использовать для однократного вызова какого-то метода через определенный интервал времени. При это создавать отдельную переменную в классе, в котором находится этот метод не обязательно.

<code data-result="[object Object]">[NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(myMethod) userInfo:nil repeats:NO];</code>

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

Но с другой стороны, это можно сделать и вот так:

<code data-result="[object Object]">[self performSelector:@selector(myMethod) withObject:nil afterDelay:10.0f];</code>

В этом случае таймер даже не буден создан, просто через 10 секунд выполнится метод myMethod.

 

Исходный код этого проекта можно скачать здесь.

Comments are closed.