Цель C: приложение зависает при использовании таймера - PullRequest
2 голосов
/ 22 декабря 2010

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

В моем main.m:

int main (int argc, const char * argv[]) {  
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

 OutLauncher *theLauncher = [[OutLauncher alloc] init];
NSTimer *theTimer = [theLauncher getTimer];
[theTimer retain];
[[NSRunLoop currentRunLoop] addTimer: theTimer forMode: NSDefaultRunLoopMode];

 [[NSRunLoop currentRunLoop] run];

 [pool release];
 return 0;  
 }

В него импортируется файл OutLauncher, который выглядит так:

- (void)doStuff {  
NSLog( @"Doing Stuff");  

}

 - (NSTimer *)getTimer{  
 NSTimer *theTimer;

 theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector: @selector(doStuff) userInfo:nil repeats:YES];

 return [theTimer autorelease];
}

Таймер работает, консольобновляется каждую секунду фразой «делать вещи», но остальная часть программы просто не загружается.Это произойдет, если я закомментирую код, который я добавил в int main, хотя

Ответы [ 3 ]

1 голос
/ 22 декабря 2010

Несколько вещей:

Вам не нужно автоматически высвобождать таймер, который вы возвращаете после настройки с помощью [NSTimer scheduleTimerWithTimeInterval:] Он уже автоматически выпущен.

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

[[NSRunLoop currentRunLoop] addTimer: theTimer forMode: NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];

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

0 голосов
/ 23 декабря 2010

Похоже, вы делаете это намного сложнее, чем нужно.Вам не нужно помещать какой-либо код в ваш файл main.m.Если вы хотите запускать метод doStuff каждую секунду, это весь код, который вам нужен:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector: @selector(doStuff) userInfo:nil repeats:YES];

Вам не нужно (автоматически) освобождать его самостоятельно.timer уже автоматически выпущен.Если вы хотите иметь возможность отменить таймер, вам нужно будет сохранить ссылку на него.Затем, когда вы хотите отменить, вы просто позвоните invalidate и установите ссылку на nil.

0 голосов
/ 22 декабря 2010

Вот что Apple говорит о том, что вы делаете в документации

пробег

переводит приемник в постоянный цикл, в течение которого он обрабатывает данные из всех подключенных источников ввода.

  • (void) запустить Обсуждение Если к входу не подключены источники входного сигнала или таймеры запустить цикл, этот метод выходит немедленно; в противном случае он запускает получатель в NSDefaultRunLoopMode неоднократно вызывая RunMode: beforeDate :. Другими словами, этот метод эффективно начинает бесконечный цикл, который обрабатывает данные из входные источники цикла выполнения и таймеры.

Вручную удаляя все известные данные источники и таймеры из цикла выполнения не является гарантией того, что цикл запуска выйдет. Mac OS X можно установить и удалить дополнительные входные источники как необходимо обрабатывать запросы, направленные на поток получателя. Эти источники поэтому может предотвратить цикл выполнения от выхода.

Если вы хотите завершить цикл выполнения, Вы не должны использовать этот метод. Вместо этого используйте один из других прогонов методы, а также проверить другие произвольные ваши собственные условия, в цикле. простой пример:

BOOL shouldKeepRunning = YES;
// глобальный NSRunLoop * theRL = [NSRunLoop currentRunLoop]; в то время как (shouldKeepRunning && [theRL RunMode: NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]); где shouldKeepRunning имеет значение NO где-то еще в программе.

Доступность Доступно в iOS 2.0 и позже.

Похоже, ваш код делает то, что должен делать. Он регистрирует все события таймера и ждет в течение неопределенного времени цикла выполнения.

...