• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
CocoaHeads Toulouse - Marc Boudou / FreezySnail - Programmation concurrente
 

CocoaHeads Toulouse - Marc Boudou / FreezySnail - Programmation concurrente

on

  • 3,127 views

Présentation du CocoaHeads Toulouse - Janvier 2012.

Présentation du CocoaHeads Toulouse - Janvier 2012.

Programmation concurrente.

par Marc Boudou, FreezySnail

Statistics

Views

Total Views
3,127
Views on SlideShare
821
Embed Views
2,306

Actions

Likes
2
Downloads
0
Comments
0

2 Embeds 2,306

http://cocoaheads.fr 2291
http://feeds.feedburner.com 15

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

CC Attribution-NonCommercial LicenseCC Attribution-NonCommercial License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

CocoaHeads Toulouse - Marc Boudou / FreezySnail - Programmation concurrente CocoaHeads Toulouse - Marc Boudou / FreezySnail - Programmation concurrente Presentation Transcript

  • Blocks et programmation concurrente sous iOS Marc Boudou Freezy Snail Janvier 2012Monday, January 16, 12
  • Programmation concurrente Exécutions de plusieurs tâches en parallèle : • Tâche en background (UI non bloquant) • Performance : multiplication des coeursMonday, January 16, 12
  • Programmation concurrente Exécutions de plusieurs tâches en parallèle : • Tâche en background (UI non bloquant) • Performance : multiplication des coeurs Solutions : • Gérer les threads soit même • Utiliser les frameworks fournis par AppleMonday, January 16, 12
  • 3 parties 1. Blocks 2. Dispatch Queue : Grand Central Dispatch 3. Operation Queue : NSOperation et NSOperationQueueMonday, January 16, 12
  • Blocks • Extension Objective C • Depuis iOS 4.0Monday, January 16, 12
  • Exemple d’utilisation Suppression dune vue avec fondu 1 . [UIView beginAnimations:@"Anim" context:nil]; 2 . [UIView setAnimationDelegate:self]; 3 . [UIView setAnimationDuration:0.6 ]; 4 . [UIView setAnimationDidStopSelector: @selector(fadeAnimationDidStop:finished:context:)]; 5 . myView.alpha = 0; 6 . [UIView commitAnimations];Monday, January 16, 12
  • Exemple d’utilisation Suppression dune vue avec fondu 1 . [UIView beginAnimations:@"Anim" context:nil]; 2 . [UIView setAnimationDelegate:self]; 3 . [UIView setAnimationDuration:0.6 ]; 4 . [UIView setAnimationDidStopSelector: @selector(fadeAnimationDidStop:finished:context:)]; 5 . myView.alpha = 0; 6 . [UIView commitAnimations]; ... - (void) fadeAnimationDidStop:(NSString *) animId finished:(NSNumber *) finished context:(void *) context { [myView removeFromSuperview]; }Monday, January 16, 12
  • Exemple d’utilisation Suppression dune vue avec fondu 0.6 myView.alpha = 0; [myView removeFromSuperview];Monday, January 16, 12
  • Exemple d’utilisation Suppression dune vue avec fondu 0.6 myView.alpha = 0; [myView removeFromSuperview];Monday, January 16, 12
  • Exemple d’utilisation Suppression dune vue avec fondu [UIView animateWithDuration:0.6 animations:^{ myView.alpha = 0; } completion:^(BOOL finished) {[myView removeFromSuperview];}];Monday, January 16, 12
  • Exemple d’utilisation Suppression dune vue avec fondu [UIView animateWithDuration:0.6 animations:^{ myView.alpha = 0; } completion:^(BOOL finished) {[myView removeFromSuperview];}]; • Code au même endroit • Accès direct au contexte • Blocks : remplace le couple delegate/selectorMonday, January 16, 12
  • Exemple : NSURLConnection NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/"]; NSURLRequest* request = [NSURLRequest requestWithURL:url]; NSURLConnection * conn = [NSURLConnection connectionWithRequest:request delegate:self];Monday, January 16, 12
  • Exemple : NSURLConnection NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/"]; NSURLRequest* request = [NSURLRequest requestWithURL:url]; NSURLConnection * conn = [NSURLConnection connectionWithRequest:request delegate:self]; NSURLConnection Delegate : - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { }Monday, January 16, 12
  • Exemple : NSURLConnection NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/"]; NSURLRequest* request = [NSURLRequest requestWithURL:url]; NSURLConnection * conn = [NSURLConnection connectionWithRequest:request delegate:self]; NSURLConnection Delegate : - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { } • Code séparé • Gestion complexe si on veut faire plusieurs requêtes dans la même classeMonday, January 16, 12
  • Solution : Création de blocks Exemple : FSHttpRequest (encapsulation de NSURLConnection)Monday, January 16, 12
  • Solution : Création de blocks Exemple : FSHttpRequest (encapsulation de NSURLConnection) NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setCompletionBlock:^ { // code connectionDidFinishLoading }]; [request setFailedBlock:^(NSError* error) { // code didFailWithError }]; [request start]; // asynchroneMonday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}];Monday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;}Monday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;} ^ void (BOOL finished) {[myView removeFromSuperview];}Monday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;} ^ void (BOOL finished) {[myView removeFromSuperview];} • Block = ObjetMonday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;} ^ void (BOOL finished) {[myView removeFromSuperview];} • Block = Objet void (^myBlock)(BOOL); // déclaration variableMonday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;} ^ void (BOOL finished) {[myView removeFromSuperview];} • Block = Objet void (^myBlock)(BOOL); // déclaration variable myBlock = ^ (BOOL finished) {[myView removeFromSuperview];} // affectationMonday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;} ^ void (BOOL finished) {[myView removeFromSuperview];} • Block = Objet void (^myBlock)(BOOL); // déclaration variable myBlock = ^ (BOOL finished) {[myView removeFromSuperview];} // affectation myBlock(true); // utilisationMonday, January 16, 12
  • Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;} ^ void (BOOL finished) {[myView removeFromSuperview];} • Block = Objet void (^myBlock)(BOOL); // déclaration variable myBlock = ^ (BOOL finished) {[myView removeFromSuperview];} // affectation myBlock(true); // utilisation int i = anotherBlock(); // utilisation autre blockMonday, January 16, 12
  • Solution : Création de blocks Exemple : FSHttpRequest (encapsulation de NSURLConnection) NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setCompletionBlock:^ { // code connectionDidFinishLoading }]; [request setFailedBlock:^(NSError* error) { // code didFailWithError }]; [request start]; // asynchroneMonday, January 16, 12
  • FSHttpRequest : .h @interface FSHttpRequest { ! // variables pointant vers un block ! void (^completionBlock)(void); void (^failedBlock)(NSError*); }Monday, January 16, 12
  • FSHttpRequest : .h typedef void (^BasicBlock)(void); typedef void (^ErrorBlock)(NSError* error); @interface FSHttpRequest { ! // variables pointant vers un block ! void (^completionBlock)(void); void (^failedBlock)(NSError*); }Monday, January 16, 12
  • FSHttpRequest : .h typedef void (^BasicBlock)(void); typedef void (^ErrorBlock)(NSError* error); @interface FSHttpRequest { ! // variables pointant vers un block ! BasicBlock completionBlock; ErrorBlock failedBlock; }Monday, January 16, 12
  • FSHttpRequest : .h typedef void (^BasicBlock)(void); typedef void (^ErrorBlock)(NSError* error); @interface FSHttpRequest { ! // variables pointant vers un block ! BasicBlock completionBlock; ErrorBlock failedBlock; } - (void)setCompletionBlock:(BasicBlock)aCompletionBlock; - (void)setFailedBlock:(ErrorBlock)aFailedBlock;Monday, January 16, 12
  • FSHttpRequest : .m @implementation FSHttpRequest @endMonday, January 16, 12
  • FSHttpRequest : .m @implementation FSHttpRequest - (void)setCompletionBlock:(BasicBlock)aCompletionBlock { ! [completionBlock release]; ! completionBlock = [aCompletionBlock copy]; // block créé sur la pile, copy permet de le déplacer sur le tas } @endMonday, January 16, 12
  • FSHttpRequest : .m @implementation FSHttpRequest - (void)setCompletionBlock:(BasicBlock)aCompletionBlock { ! [completionBlock release]; ! completionBlock = [aCompletionBlock copy]; // block créé sur la pile, copy permet de le déplacer sur le tas } - (void)setFailedBlock:(ErrorBlock)aFailedBlock { [failedBlock release]; ! failedBlock = [aFailedBlock copy]; } @endMonday, January 16, 12
  • FSHttpRequest : .m @implementation FSHttpRequest - (void)setCompletionBlock:(BasicBlock)aCompletionBlock { ! [completionBlock release]; ! completionBlock = [aCompletionBlock copy]; // block créé sur la pile, copy permet de le déplacer sur le tas } - (void)setFailedBlock:(ErrorBlock)aFailedBlock { [failedBlock release]; ! failedBlock = [aFailedBlock copy]; } NSURLConnection Delegate : - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { ! failedBlock(error); } @endMonday, January 16, 12
  • FSHttpRequest : .m @implementation FSHttpRequest - (void)setCompletionBlock:(BasicBlock)aCompletionBlock { ! [completionBlock release]; ! completionBlock = [aCompletionBlock copy]; // block créé sur la pile, copy permet de le déplacer sur le tas } - (void)setFailedBlock:(ErrorBlock)aFailedBlock { [failedBlock release]; ! failedBlock = [aFailedBlock copy]; } NSURLConnection Delegate : - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { ! failedBlock(error); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { ! completionBlock(); } @endMonday, January 16, 12
  • FSHttpRequest : utilisation NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setCompletionBlock:^ { // code connectionDidFinishLoading }]; [request setFailedBlock:^(NSError* error) { // code didFailWithError }]; [request start]; // asynchroneMonday, January 16, 12
  • Utilisation du contexte Mise à jour dune ProgressBar lors dun téléchargement de fichierMonday, January 16, 12
  • Utilisation du contexte Mise à jour dune ProgressBar lors dun téléchargement de fichier NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/toto.zip"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setBytesReceivedBlock:^(unsigned int size, long long total) { }]; [request start];Monday, January 16, 12
  • Utilisation du contexte Mise à jour dune ProgressBar lors dun téléchargement de fichier NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/toto.zip"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setBytesReceivedBlock:^(unsigned int size, long long total) { }]; [request start]; • BytesReceivedBlock appelé lorsquon reçoit des données du serveur (NSURLConnection Delegate : didReceiveData)Monday, January 16, 12
  • Utilisation du contexte Mise à jour dune ProgressBar lors dun téléchargement de fichier NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/toto.zip"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setBytesReceivedBlock:^(unsigned int size, long long total) { label.text = [url path]; }]; [request start]; • BytesReceivedBlock appelé lorsquon reçoit des données du serveur (NSURLConnection Delegate : didReceiveData) • url : accès par copieMonday, January 16, 12
  • Utilisation du contexte Mise à jour dune ProgressBar lors dun téléchargement de fichier unsigned int nbBytesReceived = 0; NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/toto.zip"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setBytesReceivedBlock:^(unsigned int size, long long total) { label.text = [url path]; nbBytesReceived += size; progressView.nbBytesReceived = nbBytesReceived; progressView.nbBytesTotal = total; }]; [request start]; • BytesReceivedBlock appelé lorsquon reçoit des données du serveur (NSURLConnection Delegate : didReceiveData) • url : accès par copieMonday, January 16, 12
  • Utilisation du contexte Mise à jour dune ProgressBar lors dun téléchargement de fichier __block unsigned int nbBytesReceived = 0; NSURL * url = [NSURL URLWithString:@"http://www.cocoaheads.fr/toto.zip"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setBytesReceivedBlock:^(unsigned int size, long long total) { label.text = [url path]; nbBytesReceived += size; progressView.nbBytesReceived = nbBytesReceived; progressView.nbBytesTotal = total; }]; [request start]; • BytesReceivedBlock appelé lorsquon reçoit des données du serveur (NSURLConnection Delegate : didReceiveData) • url : accès par copie • nbBytesReceived : accès par référence (modification possible)Monday, January 16, 12
  • Dispatch Queue : GCDMonday, January 16, 12
  • Dispatch Queue : GCD • Basé sur libdispatch (C library) • Gère les threads à notre place • Gère les problèmes de concurrence (lock, ...)Monday, January 16, 12
  • Dispatch Queue : GCD • Basé sur libdispatch (C library) • Gère les threads à notre place • Gère les problèmes de concurrence (lock, ...) => code plus simple à écrire => utilisation automatiques des coeurs => gestion des ressources processeur optimisée (création/réutilisation de thread automatique, ...)Monday, January 16, 12
  • Notion de queueMonday, January 16, 12
  • Notion de queue • Liste FIFO de blocks à exécuter • Ajout de block dans une queue • Exécution immédiate du bloc • Gère les threads qui exécutent les blocksMonday, January 16, 12
  • Dispatch Queue : 3 typesMonday, January 16, 12
  • Dispatch Queue : 3 types • Main queue (main thread) : mise a jour de lUI • Serial Queue : exécution en série des blocks sur un seul thread • Global Queue : exécution en parallèle des blocksMonday, January 16, 12
  • Serial Queue Thread courant Block1 Block2 Block3 Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Block1 Block2 Block3 Création et ajout de blocks à la Serial Queue (FIFO) Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Block2 Block3 Création et ajout de blocks à la Serial Queue (FIFO) Block1 Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Block3 Création et ajout de blocks à la Serial Block2 Queue (FIFO) Block1 Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Création et ajout Block3 de blocks à la Serial Block2 Queue (FIFO) Block1 Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Serial queue : dispatche les blocks à Création et ajout Block3 un seul thread dans le de blocks à la Serial même ordre Block2 Queue (FIFO) Block1 Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Serial queue : dispatche les blocks à Création et ajout un seul thread dans le de blocks à la Serial même ordre Block3 Queue (FIFO) Block2 Autre Thread Serial Queue Block1Monday, January 16, 12
  • Serial Queue Thread courant Serial queue : dispatche les blocks à Création et ajout un seul thread dans le de blocks à la Serial même ordre Block3 Queue (FIFO) Block2 Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Serial queue : dispatche les blocks à Création et ajout un seul thread dans le de blocks à la Serial même ordre Queue (FIFO) Block3 Autre Thread Serial Queue Block2Monday, January 16, 12
  • Serial Queue Thread courant Serial queue : dispatche les blocks à Création et ajout un seul thread dans le de blocks à la Serial même ordre Queue (FIFO) Block3 Autre Thread Serial QueueMonday, January 16, 12
  • Serial Queue Thread courant Serial queue : dispatche les blocks à Création et ajout un seul thread dans le de blocks à la Serial même ordre Queue (FIFO) Autre Thread Serial Queue Block3Monday, January 16, 12
  • Serial Queue Thread courant Serial queue : dispatche les blocks à Création et ajout un seul thread dans le de blocks à la Serial même ordre Queue (FIFO) Autre Thread Serial QueueMonday, January 16, 12
  • Global Queue Thread courant Block1 Block2 Block3 Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
  • Global Queue Thread courant Block1 Block2 Block3 Création et ajout de blocks à la Global Queue (FIFO) Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
  • Global Queue Thread courant Block2 Block3 Création et ajout de blocks à la Global Queue (FIFO) Block1 Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
  • Global Queue Thread courant Block3 Création et ajout de blocks à la Global Block2 Queue (FIFO) Block1 Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
  • Global Queue Thread courant Création et ajout de Block3 blocks à la Global Block2 Queue (FIFO) Block1 Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
  • Global Queue Thread courant Global queue : dispatche les blocks à Création et ajout de Block3 plusieurs threads blocks à la Global Block2 Queue (FIFO) Block1 Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
  • Global Queue Thread courant Global queue : dispatche les blocks à Création et ajout de plusieurs threads blocks à la Global Queue (FIFO) Block3 Thread core 1 Thread core 2 Global Queue Block1 Block2Monday, January 16, 12
  • Global Queue Thread courant Global queue : dispatche les blocks à Création et ajout de plusieurs threads blocks à la Global Queue (FIFO) Thread core 1 Thread core 2 Global Queue Block1 Block3Monday, January 16, 12
  • Global Queue Thread courant Global queue : dispatche les blocks à Création et ajout de plusieurs threads blocks à la Global Queue (FIFO) Thread core 1 Thread core 2 Global Queue Block1Monday, January 16, 12
  • Global Queue Thread courant Global queue : dispatche les blocks à Création et ajout de plusieurs threads blocks à la Global Queue (FIFO) Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
  • Queue : Création / UtilisationMonday, January 16, 12
  • Queue : Création / Utilisation • Main Queue : dispatch_queue_t main_queue = dispatch_get_main_queue();Monday, January 16, 12
  • Queue : Création / Utilisation • Main Queue : dispatch_queue_t main_queue = dispatch_get_main_queue(); • Serial Queue : dispatch_queue_t serial_queue = dispatch_queue_create(@"QueueName", NULL); ... dispatch_release(serial_queue);Monday, January 16, 12
  • Queue : Création / Utilisation • Main Queue : dispatch_queue_t main_queue = dispatch_get_main_queue(); • Serial Queue : dispatch_queue_t serial_queue = dispatch_queue_create(@"QueueName", NULL); ... dispatch_release(serial_queue); • Global Queue : dispatch_queue_t global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); => LOW, DEFAULT, HIGHMonday, January 16, 12
  • Exemple : Calcul background + UI updateMonday, January 16, 12
  • Exemple : Calcul background + UI update dispatch_queue_t global_queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); dispatch_async(global_queue, ^ { // long calcul : transformation XML en HTML avec XSL NSString * htmlString = [self computeHtml:@"data.xml"]; dispatch_async(dispatch_get_main_queue(), ^ { [maWebView loadHTMLString:htmlString baseURL:nil]; }); });Monday, January 16, 12
  • Exemple : Calcul background + UI update dispatch_queue_t global_queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); dispatch_async(global_queue, ^ { // long calcul : transformation XML en HTML avec XSL NSString * htmlString = [self computeHtml:@"data.xml"]; dispatch_async(dispatch_get_main_queue(), ^ { [maWebView loadHTMLString:htmlString baseURL:nil]; }); }); • 1er block : ajouté à la Global Queue • 2e block : ajouté à la Main QueueMonday, January 16, 12
  • Exemple : Calcul background + UI update dispatch_queue_t global_queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); dispatch_async(global_queue, ^ { // long calcul : transformation XML en HTML avec XSL NSString * htmlString = [self computeHtml:@"data.xml"]; dispatch_async(dispatch_get_main_queue(), ^ { [maWebView loadHTMLString:htmlString baseURL:nil]; }); }); • 1er block : ajouté à la Global Queue • 2e block : ajouté à la Main Queue • Synchrone : dispatch et attente fin exécution • Asynchrone : pas d’attenteMonday, January 16, 12
  • Exemple : Calcul background + UI update dispatch_queue_t global_queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); dispatch_async(global_queue, ^ { // long calcul : transformation XML en HTML avec XSL NSString * htmlString = [self computeHtml:@"data.xml"]; dispatch_async(dispatch_get_main_queue(), ^ { [maWebView loadHTMLString:htmlString baseURL:nil]; }); }); • 1er block : ajouté à la Global Queue • 2e block : ajouté à la Main Queue • Synchrone : dispatch et attente fin exécution • Asynchrone : pas d’attente • Rendu HTML => Fin => UI updateMonday, January 16, 12
  • Operation QueueMonday, January 16, 12
  • Operation Queue • NSOperation et NSOperationQueue • API haut niveau : • NSOperationQueue : Equivalent Cocoa (Objective- C based) dune concurrent Dispatch Queue (C based) • N’utilise pas GCD pour l’instant mais multicoreMonday, January 16, 12
  • Operation Queue Différences avec Dispatch QueueMonday, January 16, 12
  • Operation Queue Différences avec Dispatch Queue • Dispatch Queue : FIFO • NSOperationQueue plus complexe mais configurable : - priorités à la volée - dépendances - opérations (pause, maxConcurrentOperationCount, ...) - annulation d’une opération - ...Monday, January 16, 12
  • Operation Queue : exempleMonday, January 16, 12
  • Operation Queue : exemple • Application avec popup de login : user/password ==> plusieurs requêtes au lancement : une seule popupMonday, January 16, 12
  • Operation Queue Thread courant NSOp1 NSOp2 NSOp3 NSOp4 NSOp5 Thread 1 NSOperation Queue maxConcurrentOperation = 1Monday, January 16, 12
  • Operation Queue NSOp5 Thread courant NSOp4 NSOp3 NSOp2 NSOp1 Thread 1 NSOperation Queue maxConcurrentOperation = 1Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOp1 NSOperation Queue maxConcurrentOperation = 1Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOp1 executing NSOperation NSOp1 Queue maxConcurrentOperation = 1Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp2 Thread 1 NSOp3 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp2 Thread 1 Thread 2 NSOp3 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp2 Thread 1 Thread 2 Thread 3 NSOp3 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant NSOp5 NSOp2 executing Thread 1 Thread 2 Thread 3 NSOp3 NSOp4 executing executing NSOp2 NSOp3 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant NSOp2 executing Thread 1 Thread 2 Thread 3 NSOp5 NSOp4 executing executing NSOp2 NSOp5 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant NSOp2 executing Thread 1 Thread 2 Thread 3 NSOp5 executing NSOp2 NSOp5 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant Thread 1 Thread 2 Thread 3 NSOp5 executing NSOp5 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue Thread courant Thread 1 Thread 2 Thread 3 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
  • Operation Queue UtilisationMonday, January 16, 12
  • Operation Queue Utilisation @interface FSHttpRequest : NSOperation { }Monday, January 16, 12
  • Rappel NSUrl * url = [NSURL URLWithString:@"http://www.cocoaheads.fr"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setCompletionBlock:^ { }]; [request startRequest];Monday, January 16, 12
  • Operation Queue Utilisation @interface FSHttpRequest : NSOperation { }Monday, January 16, 12
  • Operation Queue Utilisation @interface FSHttpRequest : NSOperation { } @implementation FSHttpRequest - (void)startRequest:(NSURLRequest *)request { } @endMonday, January 16, 12
  • Operation Queue Utilisation @interface FSHttpRequest : NSOperation { } @implementation FSHttpRequest static NSOperationQueue *queue = nil; - (void)startRequest:(NSURLRequest *)request { } @endMonday, January 16, 12
  • Operation Queue Utilisation @interface FSHttpRequest : NSOperation { } @implementation FSHttpRequest static NSOperationQueue *queue = nil; - (void)startRequest:(NSURLRequest *)request { ! if(queue == nil) { queue = [[NSOperationQueue alloc] init]; // default : une seule requête exécutée en parallèle queue.maxConcurrentOperationCount = 1; } self.request = request; [queue addOperation:self]; } @endMonday, January 16, 12
  • Operation Queue - (void)start Utilisation { // Notifications KVO isExecuting // Lancement requête [NSURLConnection connectionWithRequest:self.request delegate:self]; } - (void)finish { // Notification KVO isFinished à la queue : // Tâche supprimée de la queue, une autre peut être traitée }Monday, January 16, 12
  • Operation Queue - (void)start Utilisation { // Notifications KVO isExecuting // Lancement requête [NSURLConnection connectionWithRequest:self.request delegate:self]; } - (void)finish { // Notification KVO isFinished à la queue : // Tâche supprimée de la queue, une autre peut être traitée } NSURLConnection Delegate : - (void)connectionDidFinishLoading:(NSURLConnection *)connection { ! if(connexionOK) ! { ! ! queue.maxConcurrentOperationCount = 3; ! } ! completionBlock(); ! [self finish]; }Monday, January 16, 12
  • Operation Queue Ajouts de GCD : NSBlockOperationMonday, January 16, 12
  • Operation Queue Ajouts de GCD : NSBlockOperation • Opérations simple : utilisation de blocks avec les NSOperationQueue : NSOperationQueue * queue = [[NSOperationQueue alloc] init]; NSBlockOperation * blockOp = [NSBlockOperation blockOperationWithBlock:^{ // Some code }]; [queue addOperation:blockOp]; [queue addOperationWithBlock:^{ // Another Block }]; [queue release];Monday, January 16, 12
  • Operation Queue Ajouts de GCD : NSBlockOperation • Opérations simple : utilisation de blocks avec les NSOperationQueue : NSOperationQueue * queue = [[NSOperationQueue alloc] init]; NSBlockOperation * blockOp = [NSBlockOperation blockOperationWithBlock:^{ // Some code }]; [queue addOperation:blockOp]; [queue addOperationWithBlock:^{ // Another Block }]; [queue release]; • Dépendance entre Operations : NSBlockOperation * op1 = ...; NSBlockOperation * op2 = ...; [op2 addDependencie:op1];Monday, January 16, 12