Strona główna Kontakt Jogger

Bazylowy Jogg

O makach, życiu i innych pierdołach

Cocoa i wątki

Przez dłuższy czas zastanawiałem się, czy nadal używać POSIXowych wątków w swojej bibliotece, czy rzucić się na jakieś ciekawsze zastosowanie oryginalnych wątków Cocoa.

Dokumentacja na stronach Apple jest trochę lakoniczna, a i gugiel nie do końca pomaga. Zdecydowałem się więc rzucić trochę światła na ten banalniacki mechanizm.

Żeby odpalić nowy wątek musimy zrobić dwie podstawowe rzeczy. Mieć klasę która będzie miała metodę tego wątku (czyli takie coś, co będzie się pętlić i robić dziwne rzeczy, które są nam potrzebne) oraz użyć magicznej klasy NSThread.

Powiedzmy więc, że mamy klasę MojaKlasa i w niej metodę metodaWatku: . Nasza metoda powinna nie zwracać nic i przyjmować tylko jeden parametr typu id. Generalnie rzecz biorąc jest to strasznie podobniackie do funkcji puszczanej do pthread'a.

Żeby odpalić nasz nowy wątek wystarczy użyć jednej metody z klasy NSThread (metoda klasy, a nie obiektu, więc nic nie musimy tworzyć. Kod banalniacki podaję tutaj:



  MojaKlasa *obiekcik = [[MojaKlasa alloc] init];

  [NSThread detachNewThreadSelector: @selector(metodaWatku:) toTarget:obiekcik withObject: nil];



Co to zrobi? A mianowicie odpali w nowym wątku naszą metodę w podanym obiekcie obiekcik przekazując metodzie nil'a. Jeśli chcemy coś jej przekazać to podajemy to w ostatnim parametrze do metody detachNewThreadSelector:toTarget:withObject.

Mówiłem, że banalniackie :)

Jak zabić wątek? Zakończyć naszą metodę, albo wykonać metodę exit na obiekcie wątku (NSThread).

Oczywiście NSThread ma dodatkowo parę innych metod. Zarówno klasy jak i instancji. Pozwala na zidentyfikowanie w jakim wątku się aktualnie znajdujemy (metoda klasy currentThread) ustawianie priorytetu wątku i tym podobne pierdoły. Ale ogólnie rzecz biorąc całość jest przepotwornie prostacka.

Mimo wszystko spodziewałem się po kolegach z Apple trochę bardziej wyszukanych sposobów. Z drugiej strony oni się bardzo cieszą z tych selektorów, mimo że często dziedziczenie po ładnej klasie było by znacznie fajniejsze.

Smuggi

selectory sa miodzio… Pamietaj, ze Obj-C jest w pelni dynamiczny: mozliwosc podmieniania obiektow w czasie dzialania aplikacji itd. itd. W przeciwienstwie do C++, nie sa tworzone „sztywne” odwolania do metod danego obiektu – ale runtime w locie je wykonuje. Stad selectory sa bardzo uzyteczne: dana metode mozesz umiescic w obiekcie dowolnej klasy.

Po drugie: w Obj-C nie masz wielodziedziczenia. Wiec sam rozumiesz, jakie byloby to utrudnienie.

bazyl

Owszem, ale mnie jakos to nie przeszkadza, szczerze mowiac. Wielodziedziczenie jest brzydkie. A dynamiczne podmienianie obiektow w runtime to jest dopiero hack :)

Same selektory sa czasem ok, ale odpalanie selektorow jest kurewsko przekomplikowane. Ale to moje zdanie oczywiscie :)

kL

Dziedziczenie było by do d.., bo byś miał tylko jeden punkt startowy na klasę.

A tak dowolna klasa może wykonywać operacje wielowątkowo.

Do tego jak chcesz istniejącą klasę przerobić na wielowątkową, to tylko zmieniasz wywołanie metody i już – bez dotykania hierarchi klas i dodawania metod.

Skomentuj:

Nick
URI
Kod: code