Che cos'è la delega e perché è importante nella programmazione iOS?

11

Al momento sto insegnando a me stesso la programmazione iOS, e un concetto che trovo davvero difficile avvolgere la mia mente è la delega. Che cos'è? Perché e come viene utilizzato? Qual è il vantaggio? La stesura tecnica del libro che sto leggendo rende difficile capire.

    
posta DCIndieDev 13.03.2013 - 04:53
fonte

2 risposte

16

Per capire delegates , devi capire protocols .

Un protocol è come un contratto di servizio. Quando un oggetto (più spesso una sottoclasse UIViewController , ma non sempre) firma quel contratto, sta dicendo "Sono interessato a fornire la logica per supportare il messaggio che mi mandi". Questo è simile a NSNotificationCenter per quanto riguarda la registrazione per un livello di interesse, la differenza essendo un oggetto che utilizza la delega può avere solo un delegate alla volta, dove più oggetti possono registrarsi per lo stesso NSNotification .

Apple utilizza la delega in modo pervasivo. Sempre di più, però, stai vedendo che Apple trasferisce molte delle API a blocks , che sono simili a callbacks in altre lingue.

Detto questo, la delega aiuta a mantenere MVC, anche se direi che la delega è un modello di progettazione in sé e per sé. Aiuta a separare i modelli dai controllori. Come nell'esempio di John Cartwright, un UITableView sa come visualizzare righe e sezioni. Sa come riutilizzare UITableViewCells per motivi di prestazioni. Conosce tutte le altre cose che un UIScrollView conosce. Ma non sa quali celle da visualizzare. Non sa cosa popolare con queste celle. Non sa quali celle da riutilizzare per un dato NSIndexPath . Questo dovrebbe essere il compito del controller, comunque. La delega consente alla vista tabella di scaricare questa logica senza vista su un oggetto che dovrebbe comunque avere quella responsabilità.

Inoltre, non sei bloccato in un delegato per l'intera vita di un oggetto. Puoi facilmente avere più origini dati per un dato UITableView e cambiarle in base al tempo di esecuzione, se necessario.

Quindi, da un lato, la delega è ottima per fornire dati e rispondere alle interazioni da un oggetto. Lo vedrai in molte classi UIKit, ad esempio UITableView , UIPickerView , UICollectionView , ecc.

Ma la delega è anche molto utile quando si desidera passare le informazioni tra gli oggetti. Puoi facilmente creare i tuoi protocolli e iscrivere i tuoi oggetti per seguirli. Inoltre, i metodi di protocollo sono @required per impostazione predefinita, ma è possibile specificare alcuni metodi come @optional . Questo può darti una certa flessibilità se ne hai bisogno. Supponiamo che tu abbia un controller di visualizzazione genitore e un controller di visualizzazione figlio. Forse stai usando la nuova API di Containment per farlo. In genere, se è necessario passare le informazioni dal genitore al figlio, lo si fa con una proprietà. Fatto. Ma cosa succede se è necessario passare le informazioni dal bambino al genitore? Forse qualcosa cambia nel bambino e devi avvisare il genitore. Certo, potresti fare qualche KVO su certi valori. Ma forse vuoi sapere quando viene premuto un pulsante. Basta creare un nuovo protocollo nel controller della vista figlio

@protocol MyChildDelegate
- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController;
@end

@interface MyChildViewController : UIViewController

@property (weak, nonatomic) id <MyChildDelegate> delegate;

@end

In MyChildViewController, quando il tuo pulsante viene toccato, controlla semplicemente se il tuo delegato risponde al messaggio delegato (se è richiesto e il tuo delegato non implementa il metodo, andrai in crash. Puoi rendere il metodo @optional se è necessario) e inviarlo:

- (IBAction)someButtonTapped:(id)sender {
    if ([self.delegate respondsToSelector:@selector(buttonWasTappedInChild:)]) {
        [self.delegate buttonWasTappedInChild:self];
    }
}

Quindi imposta il delegato di MyChildViewController su self e implementa - (void)buttonWasTappedInChild:(MyChildViewController *)childViewController nel tuo controller di visualizzazione padre. BOOM! Hai informazioni passate da un bambino fino al genitore. La relazione tra i due oggetti non ha nemmeno bisogno di essere il più vicino come genitore / figlio. È un contratto di servizio, quindi finché l'oggetto che si registra accetta la sua parte dell'accordo, implementando i metodi richiesti, sei d'oro!

NOTA: i delegati dovrebbero essere deboli / assegnare le proprietà, altrimenti entrerai in un ciclo di conservazione in cui nessuno dei due oggetti può essere deallocato.

Spero che questo aiuti!

    
risposta data 13.03.2013 - 15:03
fonte
2

I delegati sono oggetti che implementano determinate funzioni quando non ha senso implementare tali funzioni sull'oggetto normale. È una forma di iniezione di dipendenza.

Per un esempio concreto, guarda il protocollo UITableViewDelegate. Questi metodi non hanno senso per una vista tabella da implementare direttamente, perché le azioni per selezionare una riga di visualizzazione tabella saranno diverse in ogni app e forse in ogni vista tabella. Il delegato ha un metodo -tableView:didSelectRowAtIndexPath: in modo da poter creare un oggetto che gestisca la selezione delle righe senza creare sottoclassi della vista tabella per ogni azione separata che desideri implementare.

    
risposta data 13.03.2013 - 05:20
fonte

Leggi altre domande sui tag