我有一個NSRunLoop對象,我附加了定時器和流。它效果很好。停止它是另一回事。CFRunLoopRun()與[NSRunLoop運行]
我使用[runLoop run]
運行循環。
如果我嘗試使用CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop])
來停止循環,則循環不會停止。如果我使用CRunLoopRun()
來啓動循環,它會起作用。我也確定調用是在正確的線程(運行我的自定義運行循環的線程)上進行的。我已用pthread_self()
進行調試。
我發現一個郵件列表存檔,開發人員說:「如果您使用NSRunLoop
的運行方法啓動循環,請不要打擾使用CRunLoopStop()
」。我可以理解爲什麼它是這樣的 - 你通常將來自同一組函數的初始化器和終結器配對。
如何在沒有「訴諸CF」的情況下停止NSRunLoop
?我沒有在NSRunLoop
上看到stop
方法。該文檔說,你可以通過三種方式停止運行循環:
- 配置運行循環與超時值運行
- 告訴運行循環停止使用
CFRunLoopStop()
- 刪除所有輸入源,但這是一種不可靠的方式來停止運行循環,因爲你永遠不知道什麼卡什麼成揹着你
好運行循環,我已經嘗試過2和有一個「醜」的感覺,因爲你必須深入研究CF. 3.是不可能的 - 我不喜歡非確定性代碼。
這給我們留下了1.如果我正確理解了文檔,您不能將「超時」添加到已存在的運行循環中。您只能在超時運行新的運行循環。如果我運行一個新的運行循環,它不會解決我的問題,因爲它只會創建一個嵌套的運行循環。我仍然會彈回舊的,我也想阻止......對吧?我可能誤解了這一個。另外,我不想用超時值運行循環。如果我這樣做,我必須在燃燒CPU週期(低超時值)和響應性(高超時值)之間進行權衡。
這是建立我現在(僞代碼-ISH):
Communicator.h
@interface Communicator : NSObject {
NSThread* commThread;
}
-(void) start;
-(void) stop;
@end
Communicator.m
@interface Communicator (private)
-(void) threadLoop:(id) argument;
-(void) stopThread;
@end
@implementation Communicator
-(void) start {
thread = [[NSThread alloc] initWithTarget:self
selector:@selector(threadLoop:)
object:nil];
[thread start];
}
-(void) stop {
[self performSelector:@selector(stopThread)
onThread:thread
withObject:self
waitUntilDone:NO];
// Code ommitted for waiting for the thread to exit...
[thread release];
thread = nil;
}
@end
@implementation Communicator (private)
-(void) stopThread {
CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);
}
-(void) threadLoop:(id) argument {
// Code ommitted for setting up auto release pool
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
// Code omitted for adding input sources to the run loop
CFRunLoopRun();
// [runLoop run]; <- not stoppable with
// Code omitted for draining auto release pools
// Code omitted for signalling that the thread has exited
}
@endif
我是什麼去做? CF常見/好的模式?我不太瞭解基金會。干擾CF層可能是危險的(關於內存破壞,不一致性,內存泄漏)?有沒有更好的模式來實現我想要實現的目標?
啊,聰明!我沒有看到'runMode'只運行一次。通過反覆啓動運行循環會產生顯着的性能損失嗎? – 2011-12-21 15:30:41
不,不存在:' - [NSRunLoop運行]'和' - [NSRunLoop runUntilDate:]'是如何工作的。 – 2011-12-21 16:13:41
如果您只將runLoopIsStopped設置爲YES,線程將不會停止。 您需要將其設置爲YES並對該runloop的線程執行操作,否則[runLoop runMode:NSDefaultRunLoopMode beforeDate:date]不會退出。 這花了我很長時間才弄清楚。 – Pada 2012-06-27 10:57:25