不負責任的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有很多利器,但是能不用多線程還是別用吧。