NSRunLoop зависает с NSTimer и любым вводом - PullRequest
1 голос
/ 07 января 2011

По какой-то причине, когда я нажимаю (нажимаю и удерживаю) на любом элементе управления, NSTimer в моем приложении зависает и не срабатывает, пока я не отпущу кнопку мыши. Он просто не срабатывает, пока у меня нажата мышь. Это хорошо для коротких периодов, но также зависает, если у меня открыто всплывающее меню или выпадающий список.

Я не уверен, что что-то упустил, но похоже, что это неправильное поведение.

Я хочу иметь возможность щелкнуть стрелку вниз NSPopUpButtonCell (или даже щелкнуть и удерживать NSTableView) без полного замораживания NSTimer (которое перерисовывает NSView).

Любые комментарии / предложения будут оценены.

NSTimer добавляется в currentRunLoop с режимом NSDefaultRunLoopMode.

Ответы [ 3 ]

8 голосов
/ 07 января 2011

Пока мышь не работает, цикл выполнения находится в NSEventTrackingRunLoopMode. Поэтому любое событие, которое не получено в очередь событий EventTracking, не будет обслуживаться до тех пор, пока runloop не вернется в соответствующий режим.

Способ обойти это - добавить таймер в цикл запуска для обоих режимов (по умолчанию и отслеживание событий).

8 голосов
/ 08 февраля 2011

Вместо добавления двух или более таймеров в разные циклы выполнения или использования многопоточности (поскольку вы не сможете обновлять пользовательский интерфейс из другого потока), просто добавьте таймер в NSRunLoopCommonModes:

NSTimer *myTimer = [NSTimer timerWithTimeInterval:RefreshInterval target:self selector:@selector(doWork) userInfo:nil repeats:YES];
  [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];
0 голосов
/ 07 января 2011

Если вы просто имеете дело с одним потоком в вашем приложении, то, что вы описали, вполне ожидаемо.По умолчанию NSTimer добавляются к текущему NSRunLoop, который, в вашем случае, также отвечает за взаимодействие с пользовательским интерфейсом.Когда он связан с обработкой пользовательского интерфейса, он не может проверить ваш таймер и «запустить» его.

Решение состоит в том, чтобы использовать многопоточность, чтобы избежать такого связывания.Вот хороший пост в блоге на эту тему: http://blog.narent.com/?p=21

РЕДАКТИРОВАТЬ: См. Сообщение Дейва для альтернативного (и более элегантного IMO) решения

Также см .:

...