我的应用中遇到了一些崩溃。当检查日志并使用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)这样的新东西吗?
答案 0 :(得分:1)
你说updateCounter正在更新UILabel,并且正在后台线程上运行的计时器中调用它。你不能这样做,你需要在主线程上更新UI视图。
您可以使用performSelectorOnMainThread或GCD(调度到主队列)。我在这篇SO帖子中使用样本进行了比较:
GCD, Threads, Program Flow and UI Updating
这篇SO文章专门提供了一个带GCD的bg计时器示例:
查看mrwalker的帖子
答案 1 :(得分:0)
任何涉及UI的调用都是不线程安全,这意味着您必须对主线程进行任何更新。
不确定您实际想要实现的目标。如果你在每个定时器“tick”上做一些计算上昂贵的东西,那么是的GCD将是你最好的利用块。
也许你可以给我们一些洞察你每次打勾的内容以及你在UILabel中展示的内容?