Реализация анонимного делегата в Objective-C? - PullRequest
24 голосов
/ 20 апреля 2009

Можно ли объявить анонимные реализации таких вещей, как делегаты в Objective-C. Я думаю, что у меня есть правильная терминология, но вот пример Java:

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

Так, например, для обработки вызова UIActionSheet я должен объявить другой метод в том же классе, что кажется немного глупым, если я хочу передать ему данные, потому что я должен был бы хранить эти данные как глобальную переменную. Вот пример удаления чего-либо с диалоговым окном подтверждения, спрашивающим, уверены ли вы:

-(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];
}

и UIActionSheetDelegate в одном классе:

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

То, что я хочу сделать, это объявить его встроенным, как я это делал в примере с java вверху. Это возможно?

Ответы [ 5 ]

17 голосов
/ 20 апреля 2009

Нет способа сделать это в Objective-C в настоящее время. Apple опубликовала некоторые работы, посвященные их усилиям по добавлению в язык блоков (действительно больше напоминающих лямбда-замыкания, чем анонимных классов). С ними вы, вероятно, сможете сделать что-то похожее на анонимного делегата.

В то же время большинство программистов Какао добавляют методы делегата в отдельную категорию в классе делегата. Это помогает сохранить код более организованным. В файле .m для класса в вашем примере я бы сделал что-то вроде этого:

@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 в окне редактора отделяет объявление и реализацию категории от основного класса '.

4 голосов
/ 20 апреля 2009

Objective-C не имеет понятия анонимных классов, таких как Java, поэтому вы не можете создать класс "inline", как в коде Java.

2 голосов
/ 17 июня 2011

Я искал что-то другое, когда натолкнулся на это, но если вы выполните поиск UIALERTVIEW + BLOCKS, вы найдете несколько хитов для выполнения встроенных UIALERTVIEW. Это то, что я использовал: ALERTVIEW с блоками

1 голос
/ 01 декабря 2009

Я считаю, что анонимные классы могут быть реализованы в Objective-C, но это займет много NSProxy магии и IMP безумия Это один из моих текущих проектов.

0 голосов
/ 27 апреля 2012

Как насчет класса, реализующего интерфейс делегата. При инициализации это займет блок. В определении делегата он вызывает этот блок.

Это позволяет нескольким UIActionSheets существовать одновременно, не сравнивая их по личности

...