2016-08-25 9 views
0

は、次のコードを考えてみましょう:クラッシュ()dispatch_source_createを呼び出して、2回連続

@interface ViewController() 
@property (nonatomic, strong) dispatch_source_t source; 
@end 

@implementation ViewController 

-(void)viewDidLoad { 
    [super viewDidLoad]; 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 
    self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 
    dispatch_resume(self.source); 
    dispatch_source_set_timer(self.source, dispatch_time(DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC), 0.2 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC); 
    dispatch_source_set_event_handler(self.source, ^{ 
     NSLog(@"%s",__func__); 
    }); 
} 

@end 

私は二度同じDISPATCH_SOURCE_TYPE_TIMERを作成するためにdispatch_source_createを使用する場合は、アプリがクラッシュします。どうして?

上記の例のように、ディスパッチソースを1回と2回作成するのに違いはありますか?彼らが言うように

libdispatch.dylib`_dispatch_xref_dispose: 
    0x10015e174 <+0>: ldr w8, [x0, #48] 
    0x10015e178 <+4>: cmp w8, #2     ; =2 
    0x10015e17c <+8>: b.hs 0x10015e184    ; <+16> 
    0x10015e180 <+12>: ret  
    0x10015e184 <+16>: stp x20, x21, [sp, #-16]! 
    0x10015e188 <+20>: adrp x20, 41 
    0x10015e18c <+24>: add x20, x20, #3849   ; =3849 
    0x10015e190 <+28>: adrp x21, 46 
    0x10015e194 <+32>: add x21, x21, #2440   ; =2440 
    0x10015e198 <+36>: str x20, [x21] 
    0x10015e19c <+40>: ldp x20, x21, [sp], #16 
-> 0x10015e1a0 <+44>: brk #0x1 
+0

は、なぜあなたはそれをやっていますか?最初のものは同じプロパティに2番目を割り当てたときにちょうど割り振り解除されます – Paulw11

+0

@ Paulw11私はそれがこのような無意味なコードであることを知っています。最初は割り当てられたときに割り当て解除されますが、次に2番目のものを再開します。私はそれがまだうまくいくと思ったが、それはした!どのように? – Jimmy

+0

ディスパッチオブジェクトの廃棄にクラッシュが発生しているため、タイミングの問題のように見えます。 – Paulw11

答えて

3

は、百聞は一見にしかずです:

detailed info

は基本的にあなたがCGDによって prohibitedであるように思わ中断ディスパッチオブジェクトを、リリースしています。

最初のタイマーがクラッシュが離れて行くようになります再開:

self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 
dispatch_resume(self.source); 
self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 
dispatch_resume(self.source); 
関連する問題