【发布时间】:2014-02-27 12:24:58
【问题描述】:
我正在使用标准(由 XCode 创建)应用程序中的运行循环进行测试。我的应用有 2 个按钮:
-
Start Loop- 以某种模式启动 runloop(参见下面的代码); -
Stop Loop- 更改self.stop标志以停止运行循环。
`
- (IBAction)stopLoop:(id)sender
{
self.stop = YES;
}
- (IBAction)startLoop:(id)sender
{
self.stop = NO;
do
{
[[NSRunLoop currentRunLoop] runMode:runLoopMode beforeDate:runLoopLimitDate];
if (self.stop)
{
break;
}
} while (YES);
}
`
在哪里:
1.runLoopMode是预定义模式之一(我尝试了每个,默认,事件跟踪,模态,连接)。
2.runLoopLimitDate[NSDate distinctFuture],或[NSDate distinctPast],或关闭特征。
3、self.stop标志位安装在其他方法中,通过按钮调用。
就是这样,我的应用程序没有任何其他代码。
AFAIU,runloop 模式是一组事件源。因此,如果我在某种模式下运行 runloop,runloop 将继续那些与此模式相关联的事件源。
默认情况下,Cocoa 在默认模式下运行 runloop,所有事件都进行得很大。但是当用户按下startLoop 按钮时,我的应用程序冻结:
。 startLoop 方法永远不会打破这个无限循环。应用程序不会向我发送任何事件,因此 UI 冻结并且用户无法按下 stopLoop 按钮。如果我运行 Core Foundation 对应项,也会出现同样的问题。
但是,当我尝试通过 NSApplication(NSWindow 的)方法 nextEventMatchingMask:untilDate:inMode:dequeue: 接收事件并传递 same strong> 模式,我收到 UI 事件。
- (IBAction)startLoop:(id)sender
{
self.stop = NO;
do
{
NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES];
if (event == nil)
{
break;
}
[NSApp sendEvent:event];
if (self.stop)
{
break;
}
} while (YES);
}
有一个问题:“为什么如果我运行默认的运行循环模式或其他方式,我无法接收事件?”
谢谢你的建议。
【问题讨论】:
-
你可能需要澄清你到底在做什么。例如,如果 other 方法 从不设置
self.stop,会发生什么情况? -
谢谢,我已经更新了我的问题。
-
你只是这样阻塞runloop,限制日期意味着在此之前runloop被阻塞。您的循环正在立即重置并因此再次阻塞。停止按钮永远不会更改以发送其操作。你想达到什么目标?
-
我正在探索运行循环。我希望,启动我的 runloop,我将能够继续事件(如简单的应用程序)但留在
while循环中,直到用户按下stopLoop按钮。你能写更详细的解释吗?我不明白,为什么我运行的 runloop 不进行事件?我尝试向beforeDate:发送不同的参数,但结果都相同。谢谢。 -
尝试
runUntilDate:使用类似[NSDate dateWithTimeIntervalSinceNow:1.0];的日期,它不应该阻止事件处理。
标签: cocoa core-foundation nsrunloop