2009-04-20 10 views
21

Czy można zadeklarować anonimowe implementacje rzeczy takich jak Delegaci w Objective-C. Chyba mam prawo terminologii, ale tutaj jest przykład Java:Anonimowa implementacja delegatów w Objective-C?

myClass.addListener(new FancyInterfaceListener({ 
    void onListenerInterestingAction(Action a){ 
     ....interesting stuff here 
    } 
}); 

Tak na przykład do obsługi połączenia UIActionSheet muszę zadeklarować innej metody w tej samej klasie, co wydaje się nieco głupie, jeśli chcę przejść to dane, ponieważ będę musiał przechowywać te dane jako zmienną globalną. Oto przykład z usunięciem coś z okna z prośbą o potwierdzenie jeśli pewne:

-(void)deleteItem:(int)indexToDelete{ 
    UIActionSheet *confirm = [[UIActionSheet alloc] initWithTitle:@"Delete Item?" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:@"Delete" otherButtonTitles:nil]; 
    [confirm showInView:self.view]; 
    [confirm release]; 
} 

i UIActionSheetDelegate w tej samej klasie:

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    if (buttonIndex == 0){ 
     [[Settings sharedSettings] removeItemAtIndex:/*need index variable here*/]; 
     [drinksTable reloadData]; 
    } 
} 

Co chcę móc wykonać jest zadeklarować inline , tak jak zrobiłem to w przykładzie Java na górze. czy to możliwe?

+0

Po prostu piszę rozwiązanie dla tego rodzaju sytuacji [tutaj] (https://github.com/GojaN/AnonymusDelegate). Pamiętaj, że jest to dowód koncepcji. –

+0

Tak, możesz to zrobić z bibliotekami innych firm, przeczytaj moją pełną odpowiedź tutaj: http://stackoverflow.com/a/33096839/440168 – k06a

Odpowiedz

17

Obecnie nie można tego zrobić w Objective-C. Apple opublikowało pewne prace dotyczące ich wysiłków, aby dodać bloki (naprawdę bardziej jak zamknięcia lambda niż anonimowe klasy) do języka. Prawdopodobnie będziesz w stanie zrobić coś podobnego do anonimowego delegata z tymi.

W międzyczasie, większość programistów Cocoa dodaje metody delegatów do osobnej kategorii w klasie delegatów. Pomaga to lepiej zorganizować kod. W pliku .m dla klasy w Twojej przykład, chciałbym zrobić coś takiego:

@interface MyClass (UIActionSheetDelegate) 
- (void)actionSheet:(UIActionSheet*)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex; 
@end 

@implementation MyClass 
//... normal stuff here 
@end 

@implementation MyClass (UIActionSheetDelegate) 
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ 
    if (buttonIndex == 0){ 
     [[Settings sharedSettings] removeItemAtIndex:/*need index variable here*/]; 
     [drinksTable reloadData]; 
    } 
} 
@end 

Xcode jest metoda okienko w oknie edytora będą oddzielne zgłoszenie i realizację tego kategoria ta z głównej klasy.

+0

Czy potrzebujesz deklaracji interfejsu dla każdego wdrażanego protokołu? Jeśli tak, to o wiele więcej pracy.(Nigdy nie zadeklarowałem metod w zaimplementowanym protokole w moim interfejsie, przy założeniu, że samo deklarowanie protokołu "zaimplementowany" było wystarczająco dobre.) –

+1

Nie, możesz zadeklarować wiele protokołów, po prostu użyj przecinka w interfejsie. Również większość kodu widziałem, zamiast używać kategorii podobnej do tej (to nie jest to, za co została zaprojektowana ta funkcja - została zaprojektowana tak, aby umożliwić rozszerzanie klas bez implementacji bez podklasy), po prostu oddziela kod do własnej sekcji w pliku z dyrektywą '#pragma mark'. –

4

Objective-C nie ma pojęcia o anonimowych klasach, takich jak Java, więc nie można utworzyć klasy "inline", jak w kodzie Java.

+0

Wystarczająco uczciwe, więc czy istnieje sposób, aby to zrobić bardziej elegancko niż stworzenie innej metody w tej samej klasie? Co jeśli chciałbym dwóch różnych arkuszy UIActionSheets? – rustyshelf

+0

W przypadku dwóch arkuszy czynności należy użyć właściwości znacznika, aby sprawdzić, która z nich nazywa się metodą delegata. Jeśli dojdziesz do wielu takich sytuacji, myślę, że odpowiedzialność tego kontrolera może być zbyt duża. Nie ma nic bardziej eleganckiego niż to, co masz. Musisz sam śledzić indeks przedmiotów, o ile wiem. – Jab

1

Wierzę, że anonimowe zajęcia można zaimplementować w Objective-C, ale zajmie to dużo magii i szaleństwa i IMP szaleństwa. To jeden z moich obecnych projektów.

2

Szukałem czegoś innego, gdy natknąłem się na to, ale jeśli wyszukasz UIALERTVIEW + BLOKI, znajdziesz kilka haseł do wykonywania wbudowanych UIALERTVIEW. To jest ten, którego używałem: ALERTVIEW w/blocks

0

Co powiesz na klasę implementującą interfejs uczestnika. Po inicjalizacji zajęłoby to blok. W definicji delegata wywołuje ten blok.

Pozwala to na jednoczesne istnienie wielu arkuszy UIActionSheets bez konieczności porównywania tożsamości.