Come creare e utilizzare i blocchi
Objective-C
Con l’ultima versione di Objective-C e iOS7 Apple ha aggiunto la possibilità di utilizzare i famosi “blocks”, in italiano Blocchi.
Questo tipo di oggetto contiene dentro di se una porzione di codice che può quindi essere eseguita o trasportata tra altri oggetti, passata come argomento dei metodi ed altro.
In realtà è qualcosa di un po’ più complesso ma per iniziare può andare bene.
La sintassi per la dichiarazione e l’utilizzo dei blocks è un po’ particolare tanto che hanno creato questo simpaticissimo sito per ricordarcela, vediamo quindi come si dichiara e si implementa un blocco:
returnType (^blockName)(parameterTypes) = ^returnType(parameters) { };
Sì, è molto particolare.
Adesso facciamo un esempio pratico di dichiarazione ed utilizzo:
- (void)viewDidLoad { [super viewDidLoad]; NSInteger (^blockTest)(NSInteger, NSInteger) = ^NSInteger(NSInteger numberOne, NSInteger numberTwo){ NSInteger result = numberOne + numberTwo; return result; }; }
Abbiamo creato un blocco chiamato “blockTest” che ritorna un NSInteger e vuole come parametri due NSInteger.
Per utilizzarlo possiamo ci basta scrivere quindi:
NSInteger result = blockTest(2, 3);
Possiamo passare anche il blocco come parametro di un metodo:
- (NSInteger)testBlock:(NSInteger (^)(NSInteger, NSInteger))block { NSInteger numberOne = 2; NSInteger numberTwo = 3; return block(numberOne, numberTwo); }
UIKit utilizza i blocchi ormai per moltissimi scopi, ad esempio UIView li utilizza per eseguire le animazioni.
Ci viene molto utile  quando vogliamo eseguire una porzione di codice prima di un’altra e quindi solo alla fine far eseguire del codice specifico (i famosi completion blocks).
Facciamo un altro esempio. Assumiamo di voler scaricare un file e solo dopo averlo scaricato, volerlo aprire.
Creiamo quindi un metodo che scarica il file da un URL e un blocco che accetta come parametro una stringa, il path finale del file scaricato:
- (void)downloadFileAtURL:(NSURL*)url withCompletion:(void(^)(NSString* filePath))completion { // codice per scaricare il file NSString* finalFilePath = @"..."; if (completion) { completion(finalFilePath); } }
Quindi, il file viene scaricato e poi, quando finito viene passato il path finale al completion block.
Quando andiamo ad utilizzare questo metodo scriveremo semplicemente:
[self downloadFileAtURL:[NSURL URLWithString:@"http://www.example.com/file.zip"] withCompletion:^(NSString *filePath) { NSLog(@"file downloaded at %@", filePath); }];
Le possibilità ovviamente sono infinite, il limite è la nostra fantasia e alle nostre necessità .
CuriositÃ
Quando passate un blocco ad un metodo ricordatevi di controllare che il blocco esista, altrimenti se passate “nil” invece che un blocco esistente l’app andrà in crash.