不负责任的apple sample
Apple的Sample说可以轮循线程是否应该退出,但是有bug
see:documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html
- (void)threadRuntime:(id)arg
{
@autoreleasepool {
GXLog(@"Thread created............>>>>>>>>>>>>>>>>>>>>>>");
NSRunLoop *rl = [NSRunLoop currentRunLoop];
[_target performSelector:_selector withObject:arg];
[_target release];
_target = nil;
BOOL exitNow = NO;
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
[threadDict setValue:[NSNumber numberWithBool:exitNow] forKey:@"ThreadShouldExitNow"];
NSDate *date = [NSDate date];
while (!exitNow) {
[rl runUntilDate:date];
exitNow = [[threadDict valueForKey:@"ThreadShouldExitNow"] boolValue];
}
[_thread release];
_thread = nil;
GXLog(@"Thread Exited............<<<<<<<<<<<<<<<<<<<<<<");
}
}
Instruments进行Time Profile是这样的:
做的题外的修改,如果这样轮询
while (!exitNow) {
[rl runUntilDate:[NSDate date]];
exitNow = [[threadDict valueForKey:@"ThreadShouldExitNow"] boolValue];
}
内存占用很恐怖
[NSDate date] autorelease来不及释放,程序最终会因为内存耗尽被系统干掉。
使用CFRunLoopRun/CFRunLoopStop正确结束NSThread
一切皆因轮询而起,那就破了轮询
- (void)threadRuntime:(id)arg
{
@autoreleasepool {
GXLog(@"Thread created............>>>>>>>>>>>>>>>>>>>>>>");
[_target performSelector:_selector withObject:arg];
[_target release];
_target = nil;
CFRunLoopRun();
[_thread release];
_thread = nil;
GXLog(@"Thread Exited............<<<<<<<<<<<<<<<<<<<<<<");
}
}
- (void)stop
{
if (!_thread) {
return;
}
CFRunLoopStop(CFRunLoopGetCurrent());
}
千万小心,stop会直接停止当前线程得RunLoop,这要求在RunLoop所在的线程执行stop, 实际情况可能在其它线程调用stop。
小结
虽然cocoa&xcode有很多利器,但是能不用多线程还是别用吧。