2012-01-28 11 views
10

Sto solo iniziando lo sviluppo di IOS ma ho qualche anno di sviluppo di ASP.net attraverso C#. Per essere onesti non ho mai avuto un reale bisogno di capire delegati/eventi ecc. Prima, so che li sto usando durante la programmazione di web.forms ma molta della funzionalità è curata dal framework, dietro le quinte .Delegati in IOS - Sono richiesti alcuni chiarimenti

Così ora che sto sviluppando in IOS sono costretto a cercare di capire come funzionano (presumo qui che la teoria dei delegati/eventi sia la stessa in tutte le lingue, forse mi sbaglio). In ogni caso, la seguente riga di codice in IOS:

if ([self.delegate respondsToSelector:@selector(startImporting:)]) 
{ 
      [self.delegate startImporting:self]; 
} 

Ho ragione di pensare che, in pseudo-codice, significa qualcosa sulla falsariga di:

Se il metodo/classe di chiamare questo metodo ha un il metodo in esso chiamato 'startImporting' quindi chiama il metodo 'startImporting' all'interno della classe chiamante.

Spero sia chiaro. Se questo è il caso allora sarebbe essenzialmente lo stesso di avere un metodo statico in C# che si potrebbe chiamare con qualcosa come:

myImportClass.startImporting(); 

Presumibilmente no, o è così che sarebbe stato fatto. Quindi, mi sto perdendo l'intero punto dei delegati, i loro benefici ecc? Ho letto quello che sono ancora e ancora e mentre ha senso, non fa mai clic, non ho mai visto (nei moduli Web) il vantaggio di usarli.

Questo diventa sempre più importante mentre mi sto spostando a utilizzare espressioni lambda in .net e sono strettamente collegati ai delegati in C# così mentre posso iniziare a usarli, preferirei sapere perché e quali vantaggi i delegati in realtà sono.

+0

Qui http://stackoverflow.com/questions/30662032/ios-callback-function -from-library è possibile trovare i dettagli di implementazione per i delegati. –

risposta

45

Il modello delegazione cacao viene utilizzato per informare (progresso rapporto, ecc .) o query (chiedere credenziali, ecc.) un altro oggetto senza sapere molto su di esso.

In genere, si utilizza un protocollo per definire i metodi che verranno chiamati sul delegato e il delegato deve quindi conformarsi a tale protocollo. È anche possibile aggiungere metodi che il delegato non ha bisogno di implementare (facoltativo). Quando lo fai, devi chiamare -respondsToSelector :, perché non sai se il delegato vuole che il particolare metodo venga chiamato o meno.

Un esempio:
Si dispone di una classe che produce qualcosa, chiamiamolo Machine e un operaio della classe Worker.La macchina deve essere regolata per l'attività:

Machine *machine = [[Machine alloc] init]; 
[machine prepareWithParameters:myParameters]; 

Ora che abbiamo la macchina vogliamo produrre una massiccia quantità di Stuff:

[machine produceStuff]; 

Va bene, abbiamo finito. Ma come facciamo a sapere quando è stata prodotta un'unità di Stuff? Potremmo avere il nostro lavoratore costantemente in piedi accanto la nostra macchina e attendere:

while (![machine isFinished]) { 
    if ([machine didProduceStuff]) { 
     Stuff *stuff = [machine producedStuff]; 
     [self doSomethingWithStuff:stuff]; 
    } 
    else { 
     // Get a very large coffee... 
    } 
} 

non sarebbe bello se la macchina ci ha informato automaticamente, quando è fatto con produzione di un'unità di Stuff?

@protocol MachineDelegate <NSObject> 
@optional 
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff; 
@end 

Aggiungiamo il worker come delegato di machine:

Worker *worker; 
Machine *machine = [[Machine alloc] init]; 
[machine prepareWithParameters:myParameters]; 
[machine setDelegate:worker]; // worker does conform to <MachineDelegate> 

[machine produceStuff]; 

Quando Machine è fatto produrre qualcosa, che verrà quindi chiamare:

if ([[self delegate] respondsToSelector:@selector(machine:didProduceStuff:)]) 
    [[self delegate] machine:self didProduceStuff:stuff]; 

Il worker riceverà quindi questo metodo e può fare qualcosa:

- (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff { 
    [self doSomethingWithStuff:stuff]; 
    if ([machine isFinished]) 
     [self shutDownMachine:machine]; 

}

Non è molto più efficiente e più semplice per il lavoratore? Ora può fare qualcosa di più produttivo che stare accanto alla macchina mentre la macchina sta ancora producendo. Ora si potrebbe aggiungere ancora più metodi per MachineDelegate:

@protocol MachineDelegate <NSObject> 
@required 
    - (void) machineNeedsMaintenance:(Machine *)machine; 
    - (void) machine:(Machine *)machine fatalErrorOccured:(Error *)error; 
    - (BOOL) machine:(Machine *)machine shouldContinueAfterProductionError:(Error *)error; 
@optional 
    - (void) machineDidEnterEcoMode:(Machine *)machine; 
    - (void) machine:(Machine *)machine didProduceStuff:(Stuff *)stuff; 
@end 

delegati può essere utilizzato anche per modificare il comportamento di un oggetto senza sottoclasse esso:

@protocol MachineDelegate <NSObject> 
@required 
    - (Color *) colorForStuffBeingProducedInMachine:(Machine *)machine; 
    - (BOOL) machineShouldGiftWrapStuffWhenDone:(Machine *)machine; 
@end 

Spero di poter aiutare a capire il beneficio di astrazione del codice usando un po 'i delegati.

+2

Risposta straordinariamente completa. Grazie! –

+2

Eccellente! ha iniziato a capire i delegati dopo aver letto questa risposta :) –

+0

Questo è il miglior esempio di delegato obiettivo-c che ho incontrato finora –

1

Comprendere il modello MVC e l'uso di protocolli e notifiche è fondamentale per cogliere l'utilizzo e lo scopo dei delegati. Pensa a loro come a tipi di responder per diversi eventi correlati a un'azione specifica.

Hera sono alcuni link utili in StackOverflow:

Speranza che aiuta

0

delegati sono utili per ottenere callback da altra classe

quindi perché usare delegato: questo è che noi chiamiamo un metodo su una classe ... è normale ... se vogliamo che la classe istanziata per farci Call back ... è lì che i delegati viene in pratico ...

semplice esempio: u scaricare canzoni da un sito che utilizza un metodo su una classe una volta la classe completa scaricando u vuole la classe di lasciare u so ..

//protocol declaration 
    @protocol DownloadProtocol <NSObject> 
    -(void)OnFinish; 
    @end 

//SOng download class 
@interface songs 
@property(Strong,nonatomic) id<DownloadProtcol> delegate; 
-(void)Download; 
@end 
@implementation songs 
-(void)Download 
{ 

///the code to download goes here 

[self callTheCallingClass]; 

} 

-(void)CallTheCallingClass 
{ 
[self.delegate OnFinish]; 
} 
@end 

// 
@interface mainclass<DownloadProtocol> 

@end 

@implementation mainclass 

-(void)viewDidload 
{ 
Songs *s=[[SOngs alloc]init]; 
s.delegate=self; 
[s download]; 
} 
-(void)OnFinish 
{ 
    NSlog(@"Called"); 
} 
@end 

1) Si veda la delegazione è ottenuta attraverso il protocollo in c obiettivo Credo che u può comprendere la sintassi di esso ...

2) Nella classe canzoni che creare una proprietà per quel protocollo lo teniamo il tipo come ID ... bcuz il tipo non è noto al momento della compilazione.

3) nella classe canzoni una volta completato il download, chiamiamo il metodo del protocollo ...

4) Nella classe prima che adottano il protocollo sintassi classe quanto sopra è sintassi che

5) l'istanziamo classe canzoni

6) quindi assegnare all'oggetto classe principale (auto) di delegare di classe canzoni

7) allora dobbiamo applicare la classe di protocollo in .m aggiungendo nome del metodo da protocollo

8) in modo da ora in poi ogni volta che classe canzoni chiamare il metodo protocollo attraverso variabile di istanza delegato .... metodo fuori protocolllo di adozione in classe principale viene eseguito

provare questo codice spero che aiuta ...

se u vogliono maggiori informazioni su questo argomento google come modello di progettazione delegato

il benifit principale è promuove debolmente accoppiati programmazione ...

Problemi correlati