iphone线程初学者问题,管理自动释放池有问题
我在一个简单的线程示例中遇到了问题。我知道我的方法还没有完成,但是现在,我想按下开始按钮,让它触发一个线程,该线程每秒递增一个计数器。我知道它正确地连接在IB中,因为NSLog告诉我它可以访问我的TimerRead方法。但随后它立即跳回最初的myThread,而没有到达updateDisplay方法并释放池,这就是为什么我猜我的程序实际上没有增加计数器的原因。我原以为我会把它放在睡眠时间或其他什么的,但最终我认为我错过了实现这一目标的正确方法。任何想法都很好。谢谢iphone线程初学者问题,管理自动释放池有问题,iphone,multithreading,Iphone,Multithreading,我在一个简单的线程示例中遇到了问题。我知道我的方法还没有完成,但是现在,我想按下开始按钮,让它触发一个线程,该线程每秒递增一个计数器。我知道它正确地连接在IB中,因为NSLog告诉我它可以访问我的TimerRead方法。但随后它立即跳回最初的myThread,而没有到达updateDisplay方法并释放池,这就是为什么我猜我的程序实际上没有增加计数器的原因。我原以为我会把它放在睡眠时间或其他什么的,但最终我认为我错过了实现这一目标的正确方法。任何想法都很好。谢谢 @implementation
@implementation MainController
-(id)initWithLabel:(UILabel *)label {
if (self = [super init]) {
countLabel = label;
[countLabel retain];
}
return self;
}
-(int)count {
return count;
}
-(void)setCount:(int) value {
count = value;
}
-(void)updateDisplay:(NSTimer *)timer {
NSLog(@"%s", __FUNCTION__);
countLabel.text = [NSString stringWithFormat:@"%i", count];
count++;
}
-(void)timerThread {
NSLog(@"%s", __FUNCTION__);
[NSTimer timerWithTimeInterval:1.0
target:self
selector:@selector(updateDisplay:)
userInfo:nil
repeats:YES];
//NSNumber *threadID = [NSNumber numberWithInt:(int)threadID];
// threadLabel = [NSString stringWithFormat:@"%@", threadID];
}
-(void)myThread {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//NSNumber *threadID = [NSNumber numberWithInt:(int)threadID];
[self performSelectorOnMainThread:@selector(timerThread)
withObject:nil
waitUntilDone:NO];
// NSLog(@"threadID in myThread: %@", threadID);
[pool release];
}
-(void)startThread {
// threadIndex = 0;
// numThreads = 0;
// NSNumber *threadID = [NSNumber numberWithInt:threadIndex++];
[self performSelectorInBackground:@selector(myThread) withObject:nil];
// NSLog(@"%i", threadIndex);
numThreads++;
}
-(void)myThreadStop {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSThread exit];
[self performSelectorOnMainThread:@selector(updateDisplay)
withObject:nil
waitUntilDone:NO];
[pool release];
}
-(void)stopThread {
[self performSelectorInBackground:@selector(myThreadStop) withObject:nil];
}
-(void) dealloc {
[countLabel release];
[super dealloc];
}
@end
简单的回答是您没有安排计时器 iOS(和其他)使用运行循环。每个线程可能有一个运行循环,主UI线程为您设置了一个运行循环。简单地说,一个运行循环保持一个要做事情的队列,要么按顺序进行,要么阻塞,直到有事情要做 使用活动UI所做的任何事情,如设置UILabel的文本,都必须在主线程上完成。在您的情况下,您已在主线程上设置(但未计划)计时器以更新计时器。安排计时器只是意味着将其添加到运行循环中 如果要执行的任务很长,最终会更新UI,则可以使用performSelectorInBackground启动长任务,并在任务完成时使用performSelectorOnMainThread更新UI 如果您有一个短期的周期性任务,例如更新时钟或计数器UI,那么您可以在希望启动计时器的同一线程上创建一个NSTimer。创建计时器时,请使用scheduledTimerWithTimeInterval变量,使其自动启动 创建重复计时器时,必须保留对其的引用,以便在释放目标之前使计时器无效。最晚,在dealloc中,您应该使计时器无效 将timerThread转换为startTimer,而不是调用startThread
-(void) startTimer {
timerMember = [[NSTimer
scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateDisplay:)
userInfo:nil
repeats:YES] retain];
}
-(void) dealloc {
[timerMember invalidate];
[timerMember release];
...
}
在我看来,你想做的事不需要任何线索。您所需要的只是NSTimer(您已经完成了);它们是一种先进的技术,如果你做得不对,它会给你带来各种各样的问题。至于计时器,DrawForward的回答非常好。