2013-01-04 5 views
6

Ho una classe, che ha un sistema basato sui delegati per l'invio di diversi tipi di richieste. usa delegato per dire all'oggetto quando la richiesta è completa e anche se è stato un successo o un errore.Come convertire un sistema di callback basato sui delegati in block-based?

Ora devo anche verificare quale tipo di richiesta è stata ricevuta in risposta all'azione appropriata.

Ho una classe wrapper che dovrebbe darmi un'interfaccia basata su blocchi per lo stesso.

Passaggio a un blocco di completamento e un blocco di errore a un metodo di richiesta che dovrebbe utilizzare internamente questa classe basata sui delegati.

E quando arriva la risposta, dovrebbe chiamare automaticamente il gestore appropriato per quel tipo di richiesta e in base al successo e all'errore.

Ho visto una domanda simile su SO, ma era un po 'poco chiaro per me, quindi per favore dare un'idea generale di come procedere, invece di contrassegnarlo come duplicato immediatamente.

risposta

2

Ecco un modo per farlo. Utilizzare questa classe RAExpendable per creare dinamicamente un delegato con un'implementazione basata su blocchi.

Diciamo che il delegato è:

@protocol XDelegate 
-(void) foo:(id)response; 
@end 

Aggiungi RAExpendable.h, RAExpendable.m dal https://github.com/evadne/RAExpendable al progetto. Aggiungere dinamicamente il metodo delegato:

RAExpendable *expendable = [RAExpendable new]; 
    [expendable addMethodForSelector:@selector(foo:) types:"[email protected]:@" block:^(id x, SEL sel, id response){ 
     NSLog(@"response is %@", response); 
    }]; 

E impostare la classe expendable come il delegato:

someObject.delegate = expendable; 

Ora, se si esegue questa operazione:

[expendable performSelector:@selector(foo:) withObject:@"OK"]; 

Si ottiene la stringa response is OK. Sostituisci NSLog con qualsiasi implementazione di successo/fallimento che ritieni opportuno. D'ora in poi, quando chiami foo:, il blocco viene eseguito.

Se si desidera modificare questo per il proprio caso di utilizzo, si noti che i parametri per questo esempio sono stati [email protected]:@, che in base alla guida Type Encoding del runtime significa: void return, self, SEL, object. self e SEL sono i due parametri nascosti presenti su ogni metodo Objective-C, il terzo parametro è il primo parametro non nascosto del metodo. La firma del blocco deve corrispondere alla firma del metodo.

+0

Qualsiasi esempio per i più argomenti? Inoltre ricevo questo messaggio quando assegna "RAExpendable" come delegato: "Assegna a" id "dal tipo incompatibile" RAExpendable * __ strong'' – atulkhatri

2

Con REKit, si può fare un delegato in modo dinamico come di seguito:

id dynamicDelegate; 
dynamicDelegate = [[NSObject alloc] init]; 
[dynamicDelegate respondsToSelector:@selector(foo:) withKey:nil usingBlock:^(id receiver, id response) { 
    NSLog(@"response is %@", response); 
}]; 
someObject.delegate = dynamicDelegate; 
+0

Works per me. E apprezzo il fatto di non dover capire da solo i tipi Objective-C! – EthanB

+0

P.S. @Kazki, hai dimenticato di aggiungere un "disconoscimento dell'autore". ;) – EthanB

Problemi correlati