2012-10-19 11 views
5

Obecnie używam GCD. Jednak słyszałem, że NSOperation jest faktycznie programem wyższego poziomu. Jest jednak o wiele bardziej złożony.Który z nich jest łatwiejszy w użyciu? GCD lub NSOperation?

W GCD, zrobić coś w tle jest po prostu skorzystać z tej funkcji pomocnika I Utworzono:

+(void)doForeGround:(void (^)())block 
{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     block(); 
    }); 
} 

+(void)doBackground:(void (^)())block 
{ 

    //DISPATCH_QUEUE_PRIORITY_HIGH 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0), ^{ 
    //dispatch_async(dispatch_get_global_queue(-2,0), ^{ 
     block(); 
    }); 
} 

-(void)doBackGround:(void (^)())block onComletion:(void (^)())onCompletion 
{ 
    [BGHPTools doBackground:^{ 
     block(); 
     [BGHPTools doForeGround:^{ 
      onCompletion(); 
     }]; 
    }]; 
} 

Will robi to z NSOperation być prostsze?

Czy brakuje mi czegoś? Jak zrobiłbym to samo w NSoperation?

Odpowiedz

6

Można zrobić podobne rzeczy z NSOperation jak robisz z GCD. Główną różnicą jest to, że NSOperation zapewnia dodatkową funkcjonalność.

Na przykład

  • NSOperation ma metodę -cancel. Kolejki wysyłkowe nie mają koncepcji anulowania; wszystkie bloki zakolejkowane w kolejce będą działać do końca.
  • NSOperationQueue ma właściwość maximumConcurrentOperationCount, której można użyć (na przykład), aby zezwalać na uruchamianie tylko 3 operacji naraz. Kolejki wysyłkowe nie mają takiej koncepcji; są one albo szeregowe, zezwalając tylko na 1 blok na raz, albo współbieżnie, pozwalając na to, że aż libdispatch jest wskazane na podstawie użycia i dostępności procesora.
  • NSOperation może być zależnym od innych NSOperation s, co pozwala odroczyć wykonanie danej operacji, dopóki wszystkie jego zależności nie działać. Inne operacje będą mogły "przeskoczyć do przodu" w kolejce podczas oczekiwania na zależną operację. Kolejki wysyłkowe zawsze są odliczane w kolejności ściśle FIFO. (Można nieco naśladować zależności pomocą dispatch_group API, ale to naprawdę skierowane do różnego rodzaju problemów.)

Teraz, jeśli nie używasz żadnej z tych cech, GCD działa dobrze. Nie ma niczego niewłaściwego przy użyciu GCD, per se. Po prostu NSOperation zapewnia wygodne opakowanie dla dodatkowych fajnych funkcji.

Oto jak chcesz przerobić swoje przykłady powyżej używając NSOperationQueue:

+(void)doForeground:(void (^)())block 
{ 
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
     NSLog(@"I'm running on the main thread!"); 
     block(); 
    }]; 
} 

+(void)doBackground:(void (^)())block 
{ 
    // Note; rather than allocating a new NSOperationQueue every time, you could 
    // allocate the queue once and just refer to that queue. For simplicity, I'll 
    // skip that here. 
    [[NSOperationQueue new] addOperationWithBlock:^{ 
     NSLog(@"I'm running asynchronously on whatever thread NSOperationQueue wants!"); 
     block(); 
    }]; 
} 

-(void)doBackground:(void (^)())block onCompletion:(void (^)())onCompletion 
{ 
    [[NSOperationQueue new] addOperationWithBlock:^{ 
     block(); 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      onCompletion(); 
     }]; 
    }]; 
} 
+0

I przypuszczam, że NSSperation również tworzyć własne zagnieżdżone stosy autorelease? –

+0

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html nie opisuje metody o nazwie new. Ah musi to być skrót do przydziału] init] –

+0

'+ new' jest dziedziczone z' NSObject', podobnie jak alloc i init. I tak, blok każdej operacji będzie żył w puli autorelease. –

4

operacja Przykładem kolejka dla porównania:

- (void)viewDidLoad 
{ 
    // ... 

    self.queue = [[NSOperationQueue alloc] init]; 

    // ... 
} 

- (void)job 
{ 
    // background activities ... 
} 

- (void)startJob 
{ 
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self 
                    selector:@selector(job) 
                    object:nil]; 
    [self.queue addOperation:op]; 
} 
+1

Lubię przy użyciu bloków :) –

+1

Oczywiście +1 tak. –