2009-10-03 15 views
6

Pracuję z pewnym kodem, który wykonuje kilka asynchronicznych operacji z różnymi wywołaniami zwrotnymi; Snow Leopard sprawił, że było to niezwykle łatwe dzięki blokom i GCD.Jak lekka jest funkcja NSOperationQueue w systemie Snow Leopard?

Dzwonię NSTask z NSBlockOperation tak:

[self.queue addOperationWithBlock:^{ 
    NSTask *task = [NSTask new]; 
    NSPipe *newPipe = [NSPipe new]; 
    NSFileHandle *readHandle = [newPipe fileHandleForReading]; 
    NSData *inData = nil; 
    [task setLaunchPath:path]; 
    [task setArguments:arguments]; 
    [task launch]; 

    while ((inData = [readHandle availableData]) && [inData length]) { 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
      // callback 
     }]; 
    } 

    [task waitUntilExit]; 
}]; 

Podejście to działa idealnie. To jak magia, o ile moje callbacki prawidłowo obsługują współbieżność.

Teraz chcę być w stanie połączyć niektóre z tych połączeń; jest to metoda "odświeżania" obiektu modelu i może zająć dużo czasu. Posiadanie funta użytkownika na przycisku odświeżania nie powinno wiązać maszyny i tak dalej.

Widzę tutaj dylemat wdrożeniowy. Mogę utworzyć całą masę kolejek - jedną dla każdego typu połączenia - i ustawić ich współbieżną liczbę operacji na 1, a następnie zadzwonić pod numer -cancelAllOperations, gdy nadejdzie czas na nowe połączenie.

Alternatywnie, mógłbym wykonać kilka ręcznych zapisów księgowych, w których aktualnie wykonywane są połączenia i zarządzać pojedynczą kolejką na obiekt modelu (tak jak ja to robię) lub mógłbym pójść jeszcze dalej i użyć globalnej kolejki.

Jak ciężki jest NSOperationQueue? Czy tworzenie kolejek to zła decyzja dotycząca architektury? Czy istnieje lepszy sposób na połączenie tych zadań?

+2

FYI, masz przeciek swoją NSTask i swoją NSPipe. + Nowy jest równoważna + alloc/-init, co oznacza, że ​​jesteś odpowiedzialny za udostępnianie ich ... które nigdy nie zrobić (w kodzie powyżej). (O ile, oczywiście, używasz GC) –

+1

To Snow Leopard-jedyny program. Na pewno mam nadzieję, że twój nowy kod tylko dla Snow Leopard zostanie zebrany. :-D –

Odpowiedz

8

Jeśli niepokoi Cię wydajność, nie zgaduj: zmień, a następnie usuń wszelkie wąskie gardła. Dodawanie kolejek jest proste; spróbuj i zobacz, co Instruments mówi o wpływie na wydajność.

Główną przyczyną tworzenia wielu kolejek jest w przypadku, gdy mają jakiś powód, dla chcących uruchomić i zatrzymać je. Jeśli chcesz uzyskać korzyści z libdispatch, możesz to zrobić, dodając operacje do głównej kolejki.

0

Po prostu używaj tylu kolejek operacji, ile chcesz. Są tutaj, aby oddzielić logiczne części twojego programu. Nie sądzę, żebyś był zbyt zaniepokojony wydajnością, o ile nie rozdzielasz setek kolejek na sekundę.

+0

Strona internetowa? Co to ma wspólnego ze stronami internetowymi? –

+0

Dzięki, jest jeszcze za wcześnie rano. :) –

1

Można dodać wiele bloków do NSBlockOperation, które będą wykonywane jednocześnie i mogą być anulowane przez anulowanie operacji zawierającej. Dopóki twoje indywidualne zadania nie muszą być serializowane, może to zadziałać.

+0

nie to docs powiedzieć: „Klasa NSBlockOperation jest beton podklasa NSOperation który zarządza współbieżne wykonanie jednego lub kilku bloków” http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/NSBlockOperation_class/Reference/Reference.html –

+0

Jim, jesteś absolutnie poprawne. Odpowiedź zaktualizowana. Dzięki. –

Powiązane problemy