5

Grand Central Dispatch mükemmeldir ve kod miktarını azaltır, ancak neden arka plan iş parçacığı üzerinde bir şey çalıştıramıyorum?karşılaştırma GCD vs. performSelectorInBackground: dispatch_async arka planda değil

- (IBAction)performSel { 
    [self performSelectorInBackground:@selector(doStuff) withObject:nil]; 
    [NSThread sleepForTimeInterval:3]; 
    [[self.view.subviews lastObject] removeFromSuperview]; 
} 

- (IBAction)gcd { 
    dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) { 
    //dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) { 
    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
    //dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
    //dispatch_async(dispatch_get_main_queue(), ^(void) { 
    //dispatch_sync(dispatch_get_main_queue(), ^(void) { 
     [self doStuff]; // only for readability, will move the code on success 
    }); 
    [NSThread sleepForTimeInterval:3]; 
    [[self.view.subviews lastObject] removeFromSuperview]; 
} 

- (void)doStuff { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 

    UIView *abortingView = [[UIView alloc]initWithFrame: self.view.bounds]; 
    abortingView.backgroundColor = [UIColor whiteColor]; 
    abortingView.alpha = 0.7; 
    [self.view insertSubview:abortingView atIndex:10]; 
    [abortingView release]; 

    [pool drain]; 
} 

[NSThread sleepForTimeInterval:3]; varsayılan bir UI işlevlerini taklit etmektir:
Ben (yorumladı işin hiçbiri) ne anlama geldiğini göstermek için örnek bir uygulama yaptık. Örneğin, birisi bir navigasyon görünümünden diğerine geçiyorsa.
Sadece yeni bir görünüm tabanlı uygulamaya kod kopyalayın, iki düğme oluşturun ve bunları bağlayın.

+0

uyumaya veya IBAction yöntemlerine yanıt olarak uzun süren görevleri yapmak her zaman kötü bir fikirdir – Felix

cevap

23

UIKit sınıfları yalnızca bir uygulamanın ana dizinden kullanılmalıdır. (IOS4'ten, bir grafik içeriğine çizim iş parçacığı güvenlidir.) UIKit öğelerini arka plan iş parçacığında kullanamazsınız.

Bu durumda, yalnızca dispatch_async (dispatch_get_main_queue(), block) komutunu kullanabilirsiniz.

dispatch_async(dispatch_get_main_queue(), ^(void) { 

O ana iş parçacığı runloop ana iş parçacığı üzerinde blok açılmasına neden olur. Bir arka plan iş parçacığında bloğu çağırır. Bunu kullanamazsınız çünkü UIKit'i blokta kullanmak istersiniz. Ve dikkatli dispatch_async (dispatch_queue_create ( olmak, bu bellek sızıntısına neden olabilir, sen dispatch_queue_create tarafından oluşturulan seri sıra serbest bırakmak zorunda.

blok yapılana kadar bekler dispatch_sync
dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) { 
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 

.

dispatch_sync(dispatch_get_main_queue(), ^(void) { 

DEAFOKLAYICI

+1

'dispatch_queue_create ("myGCDqueue", NULL) 'kullanmamalısınız çünkü sızacaksın. Bir noktada yarattığınız kuyruğu serbest bırakmanız gerekir - genellikle üzerine bir blok gönderdikten sonra – shw

İlgili konular