2009-04-20 14 views
21

E 'possibile dichiarare implementazioni anonime di cose come i delegati in Objective-C. Credo di avere il diritto terminologia, ma ecco un esempio di Java:Implementazione delegato anonimo in Objective-C?

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

Così, ad esempio, per gestire una chiamata in UIActionSheet devo dichiarare un altro metodo nella stessa classe, che sembra un po 'sciocco, se voglio passare dati, perché dovrei memorizzare tali dati come variabile globale. Ecco un esempio di cancellazione di qualcosa con una finestra di conferma che chiede se il vostro sicuro:

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

e l'UIActionSheetDelegate nella stessa classe:

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

Quello che voglio essere in grado di fare è di dichiararla in linea , proprio come ho fatto nell'esempio java in alto. È possibile?

+0

Ho appena scritto una soluzione possibile per questo tipo di situazioni [qui] (https://github.com/GojaN/AnonymusDelegate). Tieni presente che questa è una prova di concetto. –

+0

Sì, puoi farlo con le librerie di terze parti, leggi la mia risposta completa qui: http://stackoverflow.com/a/33096839/440168 – k06a

risposta

17

Attualmente non esiste un modo per farlo in Objective-C. Apple ha pubblicato alcuni lavori sui loro sforzi per aggiungere blocchi (molto più simili alle chiusure lambda rispetto alle classi anonime) alla lingua. Probabilmente saresti in grado di fare qualcosa di simile al delegato anonimo con quelli.

Nel frattempo, la maggior parte dei programmatori Cocoa aggiunge i metodi delegati a una categoria separata nella classe dei delegati. Questo aiuta a mantenere il codice più organizzato. Nel file .m per la classe nel tuo esempio, vorrei fare qualcosa di simile:

@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 

di Xcode metodo pop-up nella finestra di editor separerà dichiarazione e implementazione della categoria dalla classe principale.

+0

È necessario disporre della dichiarazione dell'interfaccia per ciascun protocollo implementato? Se è così, c'è molto più lavoro.(Non ho mai dichiarato i metodi in un protocollo implementato nella mia interfaccia, sulla premessa che semplicemente dichiarare il protocollo "implementato" era abbastanza buono.) –

+1

No, è possibile dichiarare più protocolli, basta usare una virgola nell'interfaccia. Inoltre, la maggior parte del codice che ho visto, piuttosto che usare una categoria come questa (non è proprio ciò per cui è progettata la funzionalità, è progettata per consentire di estendere le classi a cui non è stata implementata l'implementazione senza sottoclassi), separa semplicemente il codice nella propria sezione del file con la direttiva '#pragma mark'. –

4

Objective-C non ha una nozione di classi anonime come Java, quindi non è possibile creare una classe "in linea" come nel codice Java.

+0

Abbastanza corretto, quindi c'è un modo per farlo in modo più elegante rispetto alla creazione di un altro metodo nella stessa classe? Cosa succede se volevo due diversi UIActionSheets? – rustyshelf

+0

Per due fogli azione si usa la proprietà tag per vedere quale si chiama il metodo delegate. Se ti trovi in ​​molte situazioni come questa, penso che la responsabilità di quel controller potrebbe essere troppo grande. Non c'è niente di più elegante di come ce l'hai. Devi tenere traccia dell'indice dell'oggetto te stesso per quanto ne so. – Jab

1

Credo che le classi anonime possano essere implementate in Objective-C, ma ci vorranno un sacco di magia NSProxy e follia IMP. Questo è uno dei miei progetti attuali.

2

Stavo cercando qualcosa di diverso quando mi sono imbattuto in questo, ma se fai una ricerca di UIALERTVIEW + BLOCKS troverai diversi colpi per fare UIALERTVIEW in linea. Questo è quello che ho usato: ALERTVIEW w/blocks

0

Come su una classe che implementa l'interfaccia delegato. All'inizializzazione ci vorrebbe un blocco. Nella definizione del delegato chiama questo blocco.

Ciò consente a più UIActionSheets di esistere contemporaneamente senza dover confrontare l'identità.

Problemi correlati