Fark

2017-07-06 31 views
5

biz şöyle, muhafaza döngüyü kırmak için bir bloğunun içinde zayıf bir başvuru kullanmanız gerekir bildiği gibi: korumakFark

__weak id weakSelf = self; 
[self doSomethingWithABlock:^() { 
    [weakSelf doAnotherThing]; 
}] 

Ancak zayıf referanslar bozamam NSTimer tarafından neden olunan çevrim.

__weak id weakSelf = self; 
timer = [NSTimer scheduledTimerWithTimeInterval:30.0f 
             target:weakSelf 
             selector:@selector(tick) 
             userInfo:nil 
             repeats:YES]; // No luck 

Fark nedir? Zamanlayıcı hala hedefi nasıl tutabilir?

+0

,: Daha önce iOS sürümlerini desteklemek zorunda yoksa blok zayıf referans modelini keyfini böylece

Not scheduledTimerWithTimeInterval şimdi, iOS 10 blok tabanlı varyasyonu vardır ve "Zayıf" kelimesini tanımlarken genellikle "id" yerine "typeof (self)" kullanırız. – Rob

cevap

6

Seçici tabanlı NSTimer tekniğiyle ilgili tüm sorun, ona ilettiğiniz nesneye güçlü bir başvuru oluşturmasıdır. Referansı, scheduledTimerWithTimeInterval'a ilettiğiniz hedefe tuttuğunuz değişken, ister güçlü ister zayıf olsun, önemsizdir. target referansının, seçici tabanlı programlanmış zamanlayıcı programlandığı sırada nil olmadığı varsayılarak, NSTimer kendi güçlü referansını oluşturacaktır. Arama kodundaki referansların "zayıf" ve "güçlü" nitelikleri sadece ARC'nin kendi bellek yönetimi çağrılarını arayan kişinin koduna yerleştireceği anlamına gelir, ancak target sadece basit bir işaretçidir ve bu zayıf ve güçlü bilginin hiçbiri iletilmez. NSTimer. Seçici tabanlı NSTimer, zamanlayıcı invalidated olana kadar çözülmeyen kendi güçlü referansını oluşturacaktır.

Bu nedenle, seçici tabanlı yöntemle oluşturulmuş bir zamanlayıcıyı geçersiz kılmak istediğimizde, viewDidDisappear veya benzeri yerine dealloc yerine sahibiz. BTW

typeof(self) __weak weakSelf = self; 
[NSTimer scheduledTimerWithTimeInterval:30 repeats:true block:^(NSTimer * _Nonnull timer) { 
    // use weakSelf here 
}];