2012-02-01 20 views
9

Ben ana başlıkları kullanarak UI güncelleme kuyrukları kullanarak ilgili bir sorum var.Güncelleme UI'sinde dispatch_get_main_queue()

Peki, UIabelgeView ile UILabel'i gösteren bir UITableView oluşturduğumuzu varsayalım. UIImage en kullanarak .. prepareCellfor içinde uyumsuz yüklenir:

dispatch_async(t_queue, ^{ 
    //load image 
    //dispatch_async(dispatch_get_main_queue(),^{ 
    cell.imageView = image; 
    } 
}); 

Ama blok resmi getirilirken iken kullanıcı bir hücreyi (veya navigasyon görünümü denetleyicisi geri düğmesi) o hücre için DetailViewController de bir yük (basar

veya uygulamaya geri döner).

Soruma soru şudur: blok görüntüyü güncelleştirmek için ana iş parçacığı başlatıldığında ne olur? Bu iyi bir soru ...

Teşekkür

cevap

14

pencereden yüklenen olmayan bir UIView güncelleştirmeye çalışıyor hatta o boşaltmak edilmiş olabilir. Ve ARC kullanırken cevap aslında bloğun kendisinin nesneyi muhafaza etmesidir, böylece daha sonra etrafta olacaktır. Bu ince hafızadan bir tanesi. Bu hücrenin geldiği UITableView, tüm hücrelerini ayırır ve serbest bırakırsa, bu (ekran dışı olsa da) korunur ve cell.imageView = image; ödevinin tamamlanmasını sağlar, sonra serbest bırakılır.

Kontrol deneylerinin büyük bir hayranıyım ve bunu test etmek için yola çıktım, ancak bir UITableView'un birçok hareketli parçaya sahip olması (hiçbir amaç için tasarlanmış). Bu yüzden aşağıdaki gibi basit bir NSObject alt sınıfı kullanılarak, çok basit bir deneme oluşturduktan:

Açıkçası bu sınıf bana bir bloğun ( sayHello) aramak için bir işlev vermek amaçlanmıştır ve ne zaman bir NSLog de-tahsis üretecek
@implementation SayHello 
-(void)sayHello{ 
    NSLog(@"Hello"); 
} 
-(void)dealloc{ 
    NSLog(@"SayHello dead"); 
} 
@end 

.

Bu gibi benim testi yaptı:

SayHello *hello = [[SayHello alloc] init]; 
dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
    double delayInSeconds = 30.0; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
     [hello sayHello]; 
    }); 
}); 

30 saniye bile (aslında, muhafaza değildi, eğer) "Merhaba" nesne ayırması en tembel runloop zaman verir. Ancak bu 30 saniye boyunca konsol sessizdir. 30 saniyelik sürenin dolmasından hemen sonra hemen "SayHello ölü" mesajını takip eden "Merhaba" mesajını alıyorum.

Peki bu nasıl "gotcha"? Açıkçası, eğer Bloklar/ARC'nin bunu yaptığını farketmezseniz, gitmeniz gerektiğini düşündüğünüz şeylerin etrafında durabilir. Ama aynı zamanda bir UITableViewCell örneğinizle; Hücreniz bir kez görüntülenir ve bir görüntü için ağ üzerinden bir istek gönderirse, ancak blok görüntüyü beklerken hücre yeniden kullanılırsa ne olur? Şimdi, bu hücreye resmini ayarlamaya çalışan ikinci bir blok var. Eh, şimdi kaybedenin hangi görüntünün görüntüleneceğine karar vereceği bir yarış var.