一時停止したタイマーをキャンセルしてから解放しようとしていますが、「dispatch_release」を呼び出すとすぐにEXC_BAD_INSTRUCTIONを取得します。一時停止したタイマーのdispatch_source_cancelが原因でEXC_BAD_INSTRUCTIONが発生する
これは、タイマーで実行する有効な一連のアクションではありませんか?
タイマー作成&サスペンション:
@interface SomeClass: NSObject { }
@property (nonatomic, assign) dispatch_source_t timer;
@end
// Class implementation
@implementation SomeClass
@synthesize timer = _timer;
- (void)startTimer
{
dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0, 0, globalQ);
dispatch_time_t startWhen = dispatch_walltime(DISPATCH_TIME_NOW, NSEC_PER_SEC * 1);
dispatch_source_set_timer(_timer, startWhen, 1 * NSEC_PER_SEC, 5000ull);
dispatch_source_set_event_handler(_timer, ^{
// Perform a task
// If a particular amount of time has elapsed, kill this timer
if (timeConstraintReached)
{
// Can I suspend this timer within it's own event handler block?
dispatch_suspend(_timer);
}
});
dispatch_resume(_timer);
}
- (void)resetTimer
{
dispatch_suspend(_timer);
dispatch_source_cancel(_timer);
// dispatch_release causes
// 'EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
dispatch_release(_timer);
self.timer = nil;
}
@end
はまた、私はタイマーソースのevent_handlerブロック内dispatch_suspend呼び出すことができますか?
ご協力いただければ幸いです。
ああ、わかりました。すべてのdispatch_suspendは 'オブジェクトのサスペンドカウントをインクリメントする'ため、サスペンドのバランスをとるための 'dispatch_resume'が必要です。 –
event_handlerブロック内でタイマーをキャンセルまたはサスペンドすることは可能ですか?それはブロック外で発生する必要がありますか? –
そうです。私の更新された答えを見てください。ドキュメントが停止しているときには公開できないことを実際には述べていませんが、私はそれが内部的な状態であると考えています。 – mattjgalloway