Nella lezione in cui abbiamo introdotto gli oggetti UITextField
e UITextView
abbiamo parlato di delegati. Di seguito andremo ad approfondire l'argomento.
Iniziamo con il dire che la delegazione è un pattern molto utilizzato nella programmazione ad oggetti, nel quale un oggetto invia periodicamente messaggi ad un altro oggetto detto delegato informandolo per esempio di un cambio di stato o di un evento che si è verificato. A questo punto il delegato potrà eseguire alcune operazioni e per esempio aggiornare la sua interfaccia. Di conseguenza, il patern delegation, permette la comunicazione di due oggetti tramite un interfaccia detta protocollo.
Un protocollo, in Objective C, altro non è che un unico file di estensione .h
nel quale vengono dichiarati alcuni metodi. Il compito del delegato di un oggetto è proprio quello di implementare i metodi definiti all'interno del protocollo definendo quindi un comportamento associato ad un particolare evento dell'eggetto delegante.
Quello che abbiamo fatto nella lezione relativa ai TextField e TextView è stato proprio quello di implementare i protocolli di delegato di tali oggetti nella classe InsertViewController
per poi utilizzare i metodi definiti nel protocollo stesso per effettuare il dismiss della tastiera.
Quello che abbiamo fatto è stato quello di implementare delegati definiti già nell'SDK di sviluppo, ma nulla vieta allo sviluppatore di scrivere i propri protocolli da implementare in altre classi. Quello che faremo adesso è proprio questo: definire un protocollo per mettere in comunicazione l'InsertViewController
(che si occupa dell'inserimento dei dati) ed il ListViewController
(che si occuperà di mostrare i dati inseriti).
Definiamo il protocollo
Iniziamo creando un nuovo file di progetto, scegliamo come tipo di classe Objective-C protocol e nominiamo il nuovo file InsertDelegate
. Come potremo vedere verrà creato un unico file di estensione .h
nel quale inseriremo, dopo aver importato la classe Fruit
, la seguente dichiarazione:
-(void)insertNewFruit:(Fruit*)fruit;
Inseriamo solo il metodo insertNewFruit:
dato che ci interessa notificare alla classe ListViewController
l'avvenuto inserimento di un nuovo frutto.
Dichiariamo un attributo delegate nella classe InsertViewController
Adesso spostiamoci nel file InsertViewController.h ed andiamo a dichiarare l'oggetto delegate (come attributo di classe) al quale verrà associato, al momento dell'allocazione nell'AppDelegate
, un oggetto di tipo ListViewController
(ricordiamoci prima di importare la classe FruitDelegate
):
__weak id <InsertDelegate> _delegate;
Come possiamo vedere nella dichiarazione dell'attributo castiamo l'oggetto id
al tipo del delegato InsertDelegate
creato precedentemente. Infine dichiariamo la property
sull'oggetto _delegate
nel seguente modo:
@property(nonatomic,weak) id <InsertDelegate> delegate;
Terminiamo il lavoro sulla classe InsertViewController
(per quanto riguarda la dichiarazione del delegato) effettuato il synthesize
della property
appena creata nel file .m
come segue:
@synthesize delegate = _delegate;
A questo punto spostiamoci nel metodo addButtonTapped
(sempre nella classe InsertViewController.m
) e, dopo la creazione dell'oggetto Fruit
inseriamo la seguente linea di codice:
[self.delegate insertNewFruit:fruitObject];
Con questa linea notificheremo al delegate (nel nostro caso un ogetto di tipo ListViewController
) che è stato creato un nuovo oggetto Fruit
passandolo come parametro al metedo insertNewFruit:
che il delegate andrà ad implementare.
Implementiamo il delegato nella classe ListViewController
A questo punto spostiamoci nel file ListViewController.h ed implementiamo il protocollo che abbiamo creato precedentemente nel seguente modo (dopo aver importato la classe InsertDelegate
):
@interface ListViewController : UIViewController <InsertDelegate>
Posizioniamoci adesso nel file ListViewController.m
ed implementiamo il metodo di delegato come segue:
- (void)insertNewFruit:(Fruit *)fruit{
NSLog(@"Nuovo frutto!");
}
Associamo il ListViewController
come delegato dell'InsertViewController
Adesso l'infrastruttura è completa, non ci resta che associare all'oggetto InsertViewController
l'oggetto ListViewController
come delegato. Spostiamoci dunque nell'AppDelegate.m e alla fine della dichiarazione dell'oggetto InsertViewController
aggiungiamo la seguente linea di codice:
insertViewController.delegate = listViewController;
A questo punto, effettuando un Run del progetto, dopo aver compilato tutti i campi e premuto il bottone Inserisci vedremo apparire sulla console la scritta: Nuovo frutto!.
Creiamo la struttura necessaria per salvare i dati nel ListViewController
L'ultima operazione che dobbiamo eseguire è quella di salvare, all'interno dell'oggetto ListViewController
ogni oggetto Fruit
creato. Dichiariamo come attributo di classe un array nel file ListViewController.h:
NSMutableArray * _itemsList;
Effettuiamo poi l'allocazione dell'array nel metodo initWithNibName: bundle:
nel file ListViewController.m:
_itemsList = [[NSMutableArray alloc]init];
Infine, all'interno del metodo insertNewFruit:
di delegato inseriamo la seguente linea di codice:
[_itemsList addObject:fruit];
Nella prossima lezione andremo a vedere come mostrare i dati inseriti usando l'oggetto UITableView
.