2013-04-19 16 views
8

Firma Cocoa szeroko wykorzystuje delegatów, aby zapewnić (między innymi) metody wywołań zwrotnych dla operacji asynchronicznych. Jednak osobiście nienawidzę modelu delegata i sposobu, w jaki zanieczyszcza on obecną klasę procedurami obsługi dla bardzo specyficznych operacji potomnych. UIAlertView to doskonały przykład.Tworzenie anonimowych obiektów delegatów w Objective-C

Dlatego zastanawiam się, czy można po prostu utworzyć anonimowy obiekt delegowany, który spełnia wymagania protokołu delegata (takiego jak UIAlertViewDelegate) za pośrednictwem bloków i przekazać ten anonimowy obiekt wszędzie tam, gdzie oczekiwane jest odwołanie delegata.

sobie wyobrazić coś tak:

id myDelegate = @{ 
    alertView:alertView didDismissWithButtonIndex:index =^{ 
     ... 
    } 
}; 

UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:... message:... delegate:myDelegate cancelButtonTitle:... otherButtonTitles:...; 
[alertView show]; 

Słyszałem Objective-C ma kilka dobrych cech językowych dynamiczny, ale nie wiem jak po prostu dodać metodę/wybierak do obiektu. Czy można to zrobić w stosunkowo prosty sposób?

+1

Pojawiło się pytanie o całkowicie ogólnych delegatów sprzed miesiąca: http://stackoverflow.com/q/15438410/603977, a gdzieś jest starsze pytanie specyficzne dla 'UIAlertViewDegate', ale nie mogę go znaleźć na stronie za chwilę. –

+1

Możesz oczywiście utworzyć zupełnie inny obiekt dla delegata. To nie musi być np. Twój ViewController. (Ale bloki Objective-C sprawiają, że moja głowa eksploduje, więc ich unikam). –

+1

Mam nadzieję, że Apple doda API oparte na blokach do rzeczy takich jak UIAlertView, tak jak zrobiły to dla NSOpenPanel po stronie Mac. –

Odpowiedz

5

Tak, funkcje językowe, o których wspominasz, są wyświetlane za pośrednictwem objective-c runtime, ale nie ma wbudowanego narzędzia umożliwiającego dynamiczne tworzenie klas delegowanych, a api środowiska wykonawczego nie jest najbardziej przyjazną funkcją.

Istnieje biblioteka o nazwie A2DynamicDelegate, która robi dokładnie to, o czym mówisz. Nie używałem go, ale warto je zbadać.

EDYCJA: Problem z tym podejściem polega na tym, że delegaci nie są zatrzymywani, więc musisz albo zachować silne odniesienie w innym miejscu, albo dodać skojarzone odwołanie do UIAlertView. Może się okazać, że całe to zamieszanie nie jest tego warte i po prostu dodanie dodatkowej metody do kontrolera widoku działa lepiej (możesz dostosować się do protokołu delegata w rozszerzeniu klasy, aby uniknąć zanieczyszczania interfejsu).

+0

i tutaj jest [nowoczesna implementacja w BlocksKit] (https://github.com/pandamonia/BlocksKit/blob/master/BlocksKit/A2DynamicDelegate.h). – Cfr

0

Jeśli chcesz używać bloków z interfejsem API opartym na delegatach, musisz wykonać pewne podklasy. Na przykład zobacz PSAlertView, która podklasuje UIAlertView, aby zapewnić interfejs API oparty na blokach.

+0

Podklasy nie są idealne. :/ – devios1

+3

nie tylko nie jest idealny, jest zabroniony: [Klasa UIAlertView ma być używana tak jak jest i nie obsługuje podklasy. Hierarchia widoków dla tej klasy jest prywatna i nie można jej modyfikować.] (Http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html) – vikingosegundo

+2

Nie musisz należy dodać podklasę 'UIAlertView' w celu dodania API opartego na blokach.Można na przykład utworzyć klasę 'MyAlert', która jest właścicielem widoku alertu, ustawia się jako delegat i odpowiada na metody delegatów, wywołując bloki dostarczone przez kod klienta. – rickster

3

Jedną z opcji jest napisanie klasy, która opakowuje bloki dla poszczególnych metod protokołu delegata do obiektu uczestnika. Aby uzyskać szczegółowe informacje, patrz this answer.

+0

Podczas pisania oddzielnej klasy do zawijania bloków pomógłoby to w rozdzieleniu obaw, wciąż jest to strasznie dużo napowietrznych/standardowych elementów, które w przeciwnym razie powinny być całkiem proste. – devios1

2

Powinieneś rozważyć użycie kategorii, która dodaje obsługę bloków do UIAlertView, która wydaje się adresować twój przypadek użycia. UIAlertView-Blocks jest moją ulubioną, chociaż jest wiele innych.