cocoa - Cocoa 应用程序有主循环吗?

标签 cocoa runloop

在 X11 下的 Linux 上并使用 GTK+,您有一个称为“主循环”的东西。一旦启动主循环,您就有一个在应用程序的主线程中运行的计时器。您可以将该计时器设置为回调函数,这样您就拥有了一个非常好的应用程序范围计时器。

这是示例代码:

GMainLoop *loop;

if(!loop_running)
{
      display = XOpenDisplay( NULL );
      loop = g_main_loop_new(NULL, FALSE);
      g_timeout_add(1000, (GSourceFunc)callback, NULL); //1 sec laps   
      g_main_loop_run(loop);  //to stop use g_main_loop_quit ()  with the "loop" as arg
      loop_running=1;
}

我正在尝试为 Mac OS X 编写一个类似的应用程序,我使用一个简单的计时器而不是主循环:

- (void) handleTimer: (NSTimer *) timer
{
    CopyDataToDB();
} // handleTimer

- (IBAction)startStopAction:(id)sender
{

   isOn=!isOn;
   if(isOn)
   {
       // Add our timers to the EventTracking loop       
       [[NSRunLoop currentRunLoop] addTimer: time forMode: NSEventTrackingRunLoopMode];

       // Add our timers to the ModelPanel loop       
       [[NSRunLoop currentRunLoop] addTimer: time forMode: NSModalPanelRunLoopMode];
   }
   else
   {
       [timer invalidate];
   }

}

这似乎不太有效。计时器始终处于关闭状态。我也尝试过使用 NSTimer 但没有成功。 我对 Objective-C 不太熟悉,特别是 GUI 应用程序。

无论如何,有什么想法如何在 Cocoa(带有 Xcode 的 Objective-C)上实现应用程序范围的计时器吗?

谢谢!

编辑 使用 NSTimer 时,这是我在运行时遇到的错误:

**[Session started at 2009-07-12 16:49:59 -0400.]
2009-07-12 16:50:02.784 MouseClick[1490:10b] Starting
2009-07-12 16:50:02.786 MouseClick[1490:10b] *** +[NSTimer scheduledTimerWithTimeInterval:selector:userInfo:repeats:]: unrecognized selector sent to class 0xa08d54c0
2009-07-12 16:50:02.787 MouseClick[1490:10b] *** +[NSTimer scheduledTimerWithTimeInterval:selector:userInfo:repeats:]: unrecognized selector sent to class 0xa08d54c0**

The Debugger has exited with status 0.

编辑2

好的,我明白了。问题是我没有向计时器添加“目标:”。现在,当我关闭计时器时,我收到以下错误:

MouseClick(1652) malloc: * error for object 0x1645c0: double free * set a breakpoint in malloc_error_break to debug 

定时器的释放如下:

[timer invalidate]; 
[timer release]; 
timer = nil;

最佳答案

取决于您到底想做什么。大多数时候,您不应该弄乱运行循环,而只需设置一个计时器:

const float framerate = 40;
const float frequency = 1.0f/framerate;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:frequency
    target:self selector:@selector(doSomething)
    userInfo:nil repeats:YES];

现在,doSomething 方法每秒将执行大约 40 次。如果您想尽可能频繁地执行某些操作,您可以生成一个新线程:

- (void) loop
{
    while (running)
    {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        // Do something useful.
        [pool release];
    }
}

- (void) run
{
    run = YES;
    [NSThread detachNewThreadSelector:@selector(loop)
        toTarget:self withObject:nil];
}

当然,现在你有了线程,这意味着同步,并且比使用计时器更令人头疼。正如我所说,这取决于您想做什么。

回答你原来的问题:是的,Cocoa 应用程序确实有一个“主循环”,可能与 GTK 类似。由于循环已经为您创建,因此没有必要编写另一个循环 - 除非您试图弄清楚事情是如何工作的或做一些复杂的事情。请参阅Run Loop Management有关详细信息,请参阅《线程编程指南》。

如果您想简单地处理事件,默认的运行循环将为您完成。只需实现处理程序即可,即。连接到按钮等的方法。如果您想定期执行某些操作(例如更新动画等),请设置一个计时器 (NSTimer)。默认的运行循环将处理时间,并且它将根据您的需要多次调用适当的选择器。

关于cocoa - Cocoa 应用程序有主循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1116817/

相关文章:

cocoa - 在核心动画中,如何获取图层框架和旋转?

objective-c - 在 View Controller 和 OS X 之间转换

cocoa - 从计时器停止 NSRunLoop

sockets - CFWriteStreamScheduleWithRunLoop 有时有效,有时无效?

swift - RunLoopObserver 和 RunLoopActivity

objective-c - 如何在objective-c中实现特定的多重继承方案

swift - 苹果操作系统 : Any way to hide window title and not toolbar item labels?

xml - 提取信息。从 XML 到 Cocoa

ios - 为什么测试的时候会调用runloop

ios - 如何将 POSIX 文件描述符添加到 iOS 运行循环以便指示何时可以读取数据?