gpt4 book ai didi

cocoa - 将 NSTimer 放置在单独的线程中

转载 作者:行者123 更新时间:2023-12-03 16:05:34 25 4
gpt4 key购买 nike

注意:可能值得向下滚动以阅读我的编辑。

我正在尝试在单独的线程中设置 NSTimer,以便当用户与我的应用程序的 UI 交互时它继续触发。这似乎有效,但 Leaks 报告了许多问题 - 我相信我已经将其范围缩小到我的计时器代码。

当前发生的情况是 updateTimer 尝试访问绑定(bind)到我的应用程序界面中的 NSTableView 的 NSArrayController (timersController)。从那里,我抓取第一个选定的行并更改其 timeSpent 列。注意:timersController 的内容是通过 Core Data 生成的托管对象的集合。

通过阅读,我相信我应该尝试做的是在主线程上执行 updateTimer 函数,而不是在我的计时器辅助线程中。

我在这里发帖是希望有更多经验的人可以告诉我这是否是我唯一做错的事情。阅读了 Apple 关于线程的文档后,我发现它是一个极其庞大的主题领域。

NSThread *timerThread = [[[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil] autorelease];
[timerThread start];

-(void)startTimerThread
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
activeTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES] retain];

[runLoop run];
[pool release];
}
-(void)updateTimer:(NSTimer *)timer
{
NSArray *selectedTimers = [timersController selectedObjects];
id selectedTimer = [selectedTimers objectAtIndex:0];
NSNumber *currentTimeSpent = [selectedTimer timeSpent];

[selectedTimer setValue:[NSNumber numberWithInt:[currentTimeSpent intValue]+1] forKey:@"timeSpent"];
}
-(void)stopTimer
{
[activeTimer invalidate];
[activeTimer release];
}

更新

对于这次泄露,我仍然完全迷失。我知道我显然做错了什么,但我已经将我的应用程序精简到只剩下骨架,但似乎仍然找不到它。为了简单起见,我已将应用程序 Controller 代码上传到:a small pastebin 。请注意,我现在删除了计时器线程代码,而是选择在单独的运行循环中运行计时器(如此处建议的那样)。

如果我将泄漏调用树设置为隐藏缺失符号和系统库,则会显示以下输出:

编辑:屏幕截图的链接已损坏并因此被删除。

最佳答案

如果您生成新线程的唯一原因是允许计时器在用户与 UI 交互时运行,您只需将其添加到不同的运行循环模式即可:

NSTimer *uiTimer = [NSTimer timerWithTimeInterval:(1.0 / 5.0) target:self selector:@selector(uiTimerFired:) userInfo:nil repeats:YES];      
[[NSRunLoop mainRunLoop] addTimer:uiTimer forMode:NSRunLoopCommonModes];

作为此答案的附录,现在可以使用 Grand Central Dispatch 和 block 来安排计时器:

// Update the UI 5 times per second on the main queue
// Keep a strong reference to _timer in ARC
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, (1.0 / 5.0) * NSEC_PER_SEC, 0.25 * NSEC_PER_SEC);

dispatch_source_set_event_handler(_timer, ^{
// Perform a periodic action
});

// Start the timer
dispatch_resume(_timer);

稍后当不再需要计时器时:

dispatch_source_cancel(_timer);

关于cocoa - 将 NSTimer 放置在单独的线程中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2715844/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com