2009-04-20 5 views
21

Est-il possible de déclarer des implémentations anonymes de choses comme des délégués dans Objective-C. Je pense avoir le droit de terminologie, mais voici un exemple java:Implémentation de délégué anonyme dans Objective-C?

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

Ainsi, par exemple pour gérer un appel UIActionSheet Je dois déclarer une autre méthode dans la même classe, ce qui semble un peu bête si je veux passer données, parce que je devrais stocker ces données en tant que variable globale. Voici un exemple de supprimer quelque chose avec une boîte de dialogue de confirmation vous demandant si votre sûr:

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

et la UIActionSheetDelegate dans la même classe:

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

Ce que je veux être en mesure de faire est de déclarer en ligne , tout comme je l'ai fait dans l'exemple java en haut. Est-ce possible?

+0

Je viens d'écrire une solution pour ce genre posible de situations [ici] (https://github.com/GojaN/AnonymusDelegate). Gardez à l'esprit que ceci est une preuve de concept. –

+0

Oui, vous pouvez le faire avec des bibliothèques tierces, lisez ma réponse complète ici: http://stackoverflow.com/a/33096839/440168 – k06a

Répondre

17

Il n'existe actuellement aucun moyen de le faire en Objective-C. Apple a publié quelques travaux sur leurs efforts pour ajouter des blocs (vraiment plus comme des fermetures lambda que des classes anonymes) à la langue. Vous seriez probablement capable de faire quelque chose de similaire au délégué anonyme avec ceux-ci.

Dans le même temps, la plupart des programmeurs Cocoa ajouter les méthodes de déléguer à une catégorie distincte de la classe des délégués. Cela aide à garder le code plus organisé. Dans le fichier .m pour la classe dans votre exemple, je ferais quelque chose comme ceci:

@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 

méthode de Xcode pop-up dans la fenêtre de l'éditeur se séparera de la classe principale la déclaration et la mise en œuvre de la catégorie.

+0

Avez-vous besoin de la déclaration d'interface pour chaque protocole que vous implémentez? Si c'est le cas, c'est beaucoup plus de travail.(Je n'ai jamais déclaré les méthodes dans un protocole implémenté dans mon interface, sur la prémisse que déclarer simplement le protocole "implémenté" était assez bon.) –

+1

Non, vous pouvez déclarer plusieurs protocoles, utilisez simplement une virgule dans l'interface. Aussi, la plupart du code que j'ai vu, plutôt que d'utiliser une catégorie comme celle-ci (ce n'est pas vraiment pour cela), il est conçu pour vous permettre de développer des classes sans implémentation sans sous-classe), sépare simplement le code dans sa propre section dans le fichier avec la directive '#pragma mark'. –

4

Objective-C n'a pas de notion de classes anonymes comme de Java, de sorte que vous ne pouvez pas créer une classe « en ligne » comme dans le code Java.

+0

Assez juste, il n'y a donc aucun moyen de le faire plus élégamment que de créer une autre méthode dans la même classe? Et si je voulais deux UIActionSheets différentes? – rustyshelf

+0

Pour deux feuilles d'action, vous utiliseriez la propriété tag pour voir laquelle s'appelait la méthode déléguée. Si vous vous trouvez dans de nombreuses situations comme celle-ci, je pense que la responsabilité de ce contrôleur pourrait être trop grande. Il n'y a rien de plus élégant que la façon dont vous l'avez. Vous devez garder une trace de l'index de l'article, pour autant que je sache. – Jab

1

Je crois que des classes anonymes peuvent être implémentées en Objective-C, mais il faudra beaucoup de NSProxy de magie et de IMP de folie. C'est l'un de mes projets actuels.

2

Je cherchais quelque chose de différent quand je suis tombé sur cela, mais si vous effectuez une recherche pour UIAlertView + BLOCS, vous trouverez plusieurs résultats pour faire UIALERTVIEWs inline. C'est celui que je sers: ALERTVIEW w/blocks

0

Que diriez-vous d'une classe qui implémente l'interface délégué. Lors de l'initialisation, il faudrait un bloc. Dans la définition de délégué, il appelle ce bloc.

Cela permet à plusieurs UIActionSheets d'exister simultanément sans avoir à comparer sur l'identité.

Questions connexes