首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSMenu动画块主线程

NSMenu动画块主线程
EN

Stack Overflow用户
提问于 2012-10-02 18:55:35
回答 1查看 546关注 0票数 8

我有:

  • 具有自定义视图的NSStatusItem (在辅助线程中滚动文本),辅助线程更新内部状态并使用setNeedsDisplay通知主线程。
  • 在mouseDown上,会弹出一个NSMenu。
  • 但是,如果选择了NSMenu中的任何一个NSMenu,或者检测到了第二个mouseDown,并且NSMenu消失了,滚动的文本动画就会结巴。

似乎NSMenu默认视图在执行动画时阻塞了主线程。我对此进行了测试,方法是让辅助线程输出time_since_last_loop与视图的drawRect: of (这是主线程),并且只有drawRect显示口吃。定制视图的drawRect从30 fps下降到5 fps,用于几个帧。

有什么方法可以使NSMenu动画非阻塞,或者与自定义视图的drawRect并发?

EN

回答 1

Stack Overflow用户

发布于 2017-01-06 20:23:38

我使用NSTimer和NSEventTrackingRunLoopMode来解决类似的问题。

在主线程中,创建一个计时器:

代码语言:javascript
复制
    updateTimer = [[NSTimer scheduledTimerWithTimeInterval:kSecondsPerFrame target:self selector:@selector(update:) userInfo:nil repeats:YES] retain];

   // kpk important: this allows UI to draw while dragging the mouse.
   // Adding NSModalPanelRunLoopMode is too risky.
    [[NSRunLoop mainRunLoop] addTimer:updateTimer forMode:NSEventTrackingRunLoopMode];

然后在更新:例程中,检查NSEventTrackingRunLoopMode:

代码语言:javascript
复制
   // only allow status updates and drawing (NO show data changes) if App is in
   // a Modal loop, such as NSEventTrackingRunLoopMode
   NSString *runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
   if ( runLoopMode == NSEventTrackingRunLoopMode )
   {
       ... do periodic update tasks that are safe to do while
       ... in this mode
       ... I *think* NSMenu is just a window
       for ( NSWindow *win in [NSApp windows] )
       {
          [win displayIfNeeded];
       }

       return;
   }

   // do all other updates
   ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12696466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档