0

我的应用程序发生了一些崩溃。检查日志并使用 atos 时,它会告诉我崩溃的确切位置,也就是我告诉我的 NSRunLoop 运行的位置:

/**
 * Create a new thread for the timer
 *
 * @version $Revision: 0.1
 */
- (void)createTimerThread {
    NSThread *timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil];
    [timerThread start];
    [timerThread release];
}//end


/**
 * Start the actual timer
 *
 * @version $Revision: 0.1
 */
- (void)startTimerThread {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

    // Start timer
    self.countTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];

    [runLoop run];// <--- Crash happened here
    [pool release];

}//end


/**
 * Update the counter
 *
 * @version $Revision: 0.1
 */
- (void)updateCounter:(NSTimer *)theTimer {

    // Does tons of timer stuff here

}//end

如您所见,崩溃发生了,[runLoop run]但我不知道为什么。它通常发生在我第二次调用 createTimerThread 方法时。

我在这里做错了什么?我想做的只是在后台运行一个计时器,这样它就不会在主线程上,因为我需要更新一个UILabel.

我应该使用像 Grand Central Dispatch (GCD) 这样的新东西吗?

4

2 回答 2

1

你说 updateCounter 正在更新一个 UILabel ,它是从在后台线程上运行的计时器调用的。你不能这样做,你需要在主线程上更新 UI 视图。

您可以使用 performSelectorOnMainThread 或 GCD(调度到主队列)。我在此 SO 帖子上使用示例比较了两者:

GCD、线程、程序流程和 UI 更新

这篇 SO 文章专门有一个带有 GCD 的 bg 计时器示例:

iOS4 创建后台定时器

看看mrwalker的帖子

于 2011-10-17T01:40:46.107 回答
0

任何涉及 UI 的调用都不是线程安全的,这意味着您必须在主线程上进行任何更新。

不确定您实际要达到的目标。如果您在每个计时器“滴答”上做一些计算上昂贵的事情,那么是的,GCD 将是您最好的选择,使用块。

也许您可以让我们了解一下您在每个刻度上所做的事情以及您在 UILabel 中显示的内容?

于 2011-10-17T01:56:17.030 回答