2012-05-03 6 views
21

Próbuję te dwa podejścia:Wykonaj pętlę Next Run: Co jest nie tak z GCD?

dispatch_async(dispatch_get_main_queue(),^{ 
    [self handleClickAsync]; 
}); 

i

[self performSelector:@selector(handleClickAsync) withObject:nil afterDelay:0]; 

w reakcji na naciśnięcie przycisku.

Drugi pozwala UIButton aby podkreślić, jak można by się spodziewać i przeprowadzenia handleClickAsync na następnej pętli biegu (przypuszczam, że: „Jakiś czas później” na pewno). Pierwsza nie pozwala, aby instancja UIButton się zaświeciła, dopóki operacja nie zostanie całkowicie wykonana.

Co to jest poprawny sposób zrobienia tego z GCD, czy jest to tylko performSelector?

+0

Przypuszczalnie dzwonisz to od wewnątrz innej kolejce wysyłki? Jeśli tak, uruchomi wszystkie polecenia sekwencyjnie w kolejce. Czy możliwe jest wywołanie tej metody przed rozpoczęciem operacji? –

+0

Nie jestem pewien. Wzywam to bezpośrednio z 'touchesEnded', który przychodzi za darmo na podklasę' UIView' (lub Uibutton w tym przypadku). –

+0

Nie jestem pewien, dlaczego tworzysz powiązanie między dispatch_async a uruchomieniem runloopa ... –

Odpowiedz

36

Uważam, że odpowiedź jest tutaj znaleźć w discussion of the main dispatch queue:

Ta kolejka współpracuje z pętli uruchomić aplikacji (jeśli jest obecny) do przeplatania wykonanie kolejce zadań z realizacją innych źródeł zdarzeń załączonym do pętli uruchamiania.

Innymi słowy, głównym kolejka roboczych ustawia kolejkę wtórnego (obok standardowej kolejki zdarzenia dostarczonego przez UIApplicationMain() do obsługi bloków przedstawionych głównego kolejki. gdy bloki są obecne w kolejce, pętla RUN alternatywne zadania zdejmującą z kolejki od głównej kolejki zdarzeń i kolejce wysyłkowy z drugiej strony, reference dla parametru -performSelector:withObject:afterDelay: notatek delay że:.

Określanie opóźnienia 0 niekoniecznie powodować selektor być wykonywane natychmiast Selektor jest nadal w kolejce na wątku " s uruchomić pętlę i wykonać jak najszybciej.

Tak więc podczas korzystania wykonać selektora, operacja jest w kolejce na końcu głównej kolejki zdarzeń i nie będą wykonywane, dopóki wszystko przed nim w kolejce (prawdopodobnie w tym kodu usuwa zaznaczenie UIButton) zostało przetworzone. Jednak podczas korzystania z głównej kolejki wywołania dodaje blok do kolejki dodatkowej, która prawdopodobnie zostanie przetworzona natychmiast (tj. W następnej pętli uruchamiania), zakładając, że w głównej kolejce nie ma innych bloków. W tym przypadku kod, aby odświeżyć przycisk, nadal znajduje się w głównej kolejce zdarzeń, podczas gdy pętla uruchamiania przetwarza zdarzenie z kolejki bloku pomocniczego.

+0

To ma sens, Seanie, i wydaje się wyjaśniać rzeczywistość empiryczną. Zamierzam poczekać kilka dni, aby zaznaczyć to zaakceptowane, aby zobaczyć, jakie inne rodzaje odpowiedzi przychodzą. –

+0

Hmmm ... mam nadzieję, że ktoś taki jak @bbum wejdzie i zweryfikuje te rzeczy, ale to nie tylko jak działa SO, więc zaznaczę to jako tymczasowo najlepszą odpowiedź (na zawsze). Dzięki jeszcze raz. –

22

myślę, że to będzie hit punkt:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
    //bla bla bla 
}]; 
+0

To dla mnie. :) –

+0

Tak. To działa! – Klaas