Zgodnie z projektem, dispatch_*()
API nie mają pojęcia odwołania. Powodem tego jest fakt, że prawie zawsze jest prawdą, że twój kod zachowuje koncepcję, kiedy się zatrzymać, a co nie, a także, że w wysyłce _ *() API byłyby zbędne (a przy nadmiarowości pojawiają się błędy).
Tak więc, jeśli chcesz "zatrzymać wcześnie" lub w inny sposób anulować oczekujące elementy w kolejce wysyłkowej (niezależnie od tego, w jaki sposób zostały zakolejkowane), możesz to zrobić, dzieląc trochę stanu z kolejnymi blokami, które pozwalają ci Anuluj.
if (is_canceled()) return;
Lub:
__block BOOL keepGoing = YES;
dispatch_*(someQueue, ^{
if (!keepGoing) return;
if (weAreDoneNow) keepGoing = NO;
}
Należy zauważyć, że zarówno enumerateObjectsUsingBlock:
i enumerateObjectsWithOptions:usingBlock:
zarówno anulowanie wsparcie ponieważ API znajduje się w innej roli. Wywołanie metody wyliczania to synchroniczna, nawet jeśli faktyczne wykonanie bloków wyliczających może być w pełni współbieżne w zależności od opcji.
Zatem ustawienie *stopFlag=YES
mówi wyliczenie przestać. Nie gwarantuje to jednak, że zatrzyma się natychmiast w równoległym przypadku. Wyliczenie może faktycznie wykonać kilka bloków, które już są zakryte przed zatrzymaniem.
(Można krótko pomyśleć, że bardziej sensownym byłoby zwracanie numeru BOOL
w celu wskazania, czy wyliczanie powinno być kontynuowane, ponieważ wymagałoby to, aby blok wyliczający był wykonywany synchronicznie, nawet w przypadku równoczesnym, aby wartość zwracana była może być sprawdzone, byłoby to znacznie mniej wydajne.)
Cóż, to nie do końca prawda; podczas gdy prawdą jest, że enumerateObjectsUsingBlock: jest sekwencyjny, istnieje również enumerateObjectsWithOptions: usingBlock :. Ten parametr "options" może być użyty do tego, aby wyliczanie odbywało się jednocześnie. Nie jestem pewien, jak to robią wewnętrznie, ale domyślam się, że zrobiono to za pomocą grupy dispatch_group, która umożliwiałaby bardziej bezpośrednią kontrolę. –
Ale chodzi o to, że enumerateObjectsWithOptions: usingBlock: nadal ma parametr * stop. –
Logiczne byłoby wspieranie zatrzymywania w dispatch_apply(), ale nie miało to sensu w ramach celów projektowych. Stwierdzenie, że flaga stop na elemencie 'enumerateObjectsUsingBlock:' istnieje z powodu domniemanego wykonywania sekwencyjnego, jest niepoprawna; te dwie są całkowicie ortogonalne. – bbum