Подтвердить что ты не робот

Анонимная реализация делегата в Objective-C?

Можно ли объявлять анонимные реализации таких вещей, как Delegates, в 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 вверху. Возможно ли это?

4b9b3361

Ответ 1

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

В то же время большинство программистов Cocoa добавляют методы делегата к отдельной категории в классе делегата. Это помогает сохранить код более организованным. В файле .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 в окне редактора отделяет объявление категории и реализацию от основного класса.

Ответ 2

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

Это позволяет нескольким файлам UIActionSheets одновременно существовать без сравнения с идентификатором.