Come creare un protocollo delegate in Objective-C

Objective-C

Abbiamo parlato di come notificare un oggetto nell’articolo Come notificare messaggi con NSNotificationCenter, ma esiste un altro metodo per scambiare messaggi tra gli oggetti.
Si tratta di utilizzare il Delegation Pattern.

Questo pattern è molto utilizzato in Objective-C ed anche dalle classi di Cocoa, molto probabilmente ne avrete fatto uso con UITableView dove viene usato per il delegate e il datasource.

Utilizzarlo è semplice:

1.
@protocol DelegationSampleDelegate;

2.
@interface DelegationSample : NSObject

@property (nonatomic, weak) id  delegate;

@end

3.
@protocol DelegationSampleDelegate 

- (void)doThis:(DelegationSample*)delegationSample;

@end

Analizziamolo:
1. Dichiaro il protocollo così da avere un riferimento in seguito nell’header.

2. Nell’implementazione della classe è necessario avere una proprietà chiamata solitamente “delegate” di tipo id che risponde al protocollo appena creato e che sia “weak”, cioè che non riterrà l’oggetto passato.

3. Questa è la parte interessante. Qui creiamo il protocollo dichiarando i metodi che potremmo utilizzare in seguito.

E’ buona prassi passare anche l’oggetto che invia il messaggio, in questo modo avremo un riferimento chiaro di chi lo ha inviato.
Per esempio protemmo avere vari oggetti dello stesso tipo o vari oggetti che usano il medesimo protocollo e vogliamo sapere chi sta chiamando quel metodo.

Vediamo come utilizzarlo.

Assumiamo di avere un ViewController, dobbiamo far sì che sia conforme al nostro nuovo protocollo così da potersi registrare come delegate:

#import "DelegationSample.h"

@interface ViewController : UIViewController 

@end

Poi nel file di implementazione possiamo creare l’oggetto e registrarci come delegate.

- (void)viewDidLoad {
	[super viewDidLoad];

	DelegationSample* sample = [DelegationSample new];
	sample.delegate = self;
}

A questo punto possiamo utilizzare il metodo di delegate:

- (void)doThis:(DelegationSample*)delegationSample {

	NSLog(@"DelegationSample %@", delegationSample);

}

Per chiamare il metodo di delegate dall’oggetto DelegationSample invece usiamo:

- (void)foo {
	[self.delegate doThis:self];
}

Curiosità:

@protocol ha anche un’instruzione chiamata @optional che ci consente di marcare come opzionali determinati metodi:

@protocol DelegationSampleDelegate 

@optional
- (void)doThis:(DelegationSample*)delegationSample;

@end

In questo caso il metodo è opzionale, però attenzione! Dovete controllare che il delegate risponda a questo selettore prima di invocarlo:

- (void)foo {
	if ([self respondsToSelector:@selector(doThis:)]) {
		[self.delegate doThis:self];
	}
}
Scritto il