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ń?
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) –
To Snow Leopard-jedyny program. Na pewno mam nadzieję, że twój nowy kod tylko dla Snow Leopard zostanie zebrany. :-D –