NSRunLoop freezes with NSTimer and any input

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-03 02:30:06

问题


For some reason when I push down (click and hold) on any control, the NSTimer in my App freezes and does not fire until I release the mouse button. It simply does not fire while I have the mouse pressed. This is fine for short periods, but it also freezes if I have a popup menu open, or a combobox dropped down.

I'm not sure if there is something I missed, but it seems like this is incorrect behavior.

I want to be able to click the down arrow of an NSPopUpButtonCell (or even click and hold an NSTableView) without the entire NSTimer freezing (which redraws an NSView).

Any comments / suggestions would be appreciated.

The NSTimer is added to the currentRunLoop with mode NSDefaultRunLoopMode.


回答1:


While the mouse is down, the run loop is in the NSEventTrackingRunLoopMode. Therefore, any event that's not received onto the EventTracking event queue won't be serviced until the runloop returns to the appropriate mode.

The way around this is to add the timer to the runloop for both modes (default and event tracking).




回答2:


Instead of adding two or more timers to different runloops or using multithreading (as you won't then be able to update the UI from another thread) simply add the timer to the NSRunLoopCommonModes:

NSTimer *myTimer = [NSTimer timerWithTimeInterval:RefreshInterval target:self selector:@selector(doWork) userInfo:nil repeats:YES];
  [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];



回答3:


Assuming you're just dealing with one thread in your application, what you described is perfectly expected. By default, NSTimer's are added to the current NSRunLoop which, in your case, is also responsible for dealing with UI interaction. When it gets tied up with handling UI interaction, it can't check your timer and "fire" it.

A solution is to use multi-threading so as to avoid this tie-up. Here's a nice blog post on this very subject: http://blog.narent.com/?p=21

EDIT: See Dave's post for an alternative (and more elegant IMO) solution

Also see:

  • NSTimer doc
  • NSRunLoop doc
  • Threading programming guide


来源:https://stackoverflow.com/questions/4622684/nsrunloop-freezes-with-nstimer-and-any-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!