CocoaHeads Toulouse - Marc Boudou / FreezySnail - Programmation concurrente

3,646 views

Published on

Présentation du CocoaHeads Toulouse - Janvier 2012.

Programmation concurrente.

par Marc Boudou, FreezySnail

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,646
On SlideShare
0
From Embeds
0
Number of Embeds
2,597
Actions
Shares
0
Downloads
0
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide
  • \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

    1. 1. Blocks et programmation concurrente sous iOS Marc Boudou Freezy Snail Janvier 2012Monday, January 16, 12
    2. 2. 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
    3. 3. 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
    4. 4. 3 parties 1. Blocks 2. Dispatch Queue : Grand Central Dispatch 3. Operation Queue : NSOperation et NSOperationQueueMonday, January 16, 12
    5. 5. Blocks • Extension Objective C • Depuis iOS 4.0Monday, January 16, 12
    6. 6. 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
    7. 7. 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
    8. 8. Exemple d’utilisation Suppression dune vue avec fondu 0.6 myView.alpha = 0; [myView removeFromSuperview];Monday, January 16, 12
    9. 9. Exemple d’utilisation Suppression dune vue avec fondu 0.6 myView.alpha = 0; [myView removeFromSuperview];Monday, January 16, 12
    10. 10. 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
    11. 11. 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
    12. 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
    13. 13. 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
    14. 14. 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
    15. 15. Solution : Création de blocks Exemple : FSHttpRequest (encapsulation de NSURLConnection)Monday, January 16, 12
    16. 16. 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
    17. 17. Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}];Monday, January 16, 12
    18. 18. Syntaxe [UIView animateWithDuration: animations:^{myView.alpha = 0;} completion:^(BOOL finished) {[myView removeFromSuperview];}]; ^ void (void) {myView.alpha = 0;}Monday, January 16, 12
    19. 19. 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
    20. 20. 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
    21. 21. 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
    22. 22. 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
    23. 23. 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
    24. 24. 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
    25. 25. 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
    26. 26. FSHttpRequest : .h @interface FSHttpRequest { ! // variables pointant vers un block ! void (^completionBlock)(void); void (^failedBlock)(NSError*); }Monday, January 16, 12
    27. 27. 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
    28. 28. 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
    29. 29. 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
    30. 30. FSHttpRequest : .m @implementation FSHttpRequest @endMonday, January 16, 12
    31. 31. 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
    32. 32. 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
    33. 33. 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
    34. 34. 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
    35. 35. 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
    36. 36. Utilisation du contexte Mise à jour dune ProgressBar lors dun téléchargement de fichierMonday, January 16, 12
    37. 37. 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
    38. 38. 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
    39. 39. 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
    40. 40. 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
    41. 41. 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
    42. 42. Dispatch Queue : GCDMonday, January 16, 12
    43. 43. 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
    44. 44. 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
    45. 45. Notion de queueMonday, January 16, 12
    46. 46. 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
    47. 47. Dispatch Queue : 3 typesMonday, January 16, 12
    48. 48. 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
    49. 49. Serial Queue Thread courant Block1 Block2 Block3 Autre Thread Serial QueueMonday, January 16, 12
    50. 50. Serial Queue Thread courant Block1 Block2 Block3 Création et ajout de blocks à la Serial Queue (FIFO) Autre Thread Serial QueueMonday, January 16, 12
    51. 51. Serial Queue Thread courant Block2 Block3 Création et ajout de blocks à la Serial Queue (FIFO) Block1 Autre Thread Serial QueueMonday, January 16, 12
    52. 52. Serial Queue Thread courant Block3 Création et ajout de blocks à la Serial Block2 Queue (FIFO) Block1 Autre Thread Serial QueueMonday, January 16, 12
    53. 53. Serial Queue Thread courant Création et ajout Block3 de blocks à la Serial Block2 Queue (FIFO) Block1 Autre Thread Serial QueueMonday, January 16, 12
    54. 54. 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
    55. 55. 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
    56. 56. 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
    57. 57. 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
    58. 58. 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
    59. 59. 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
    60. 60. 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
    61. 61. Global Queue Thread courant Block1 Block2 Block3 Thread core 1 Thread core 2 Global QueueMonday, January 16, 12
    62. 62. 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
    63. 63. 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
    64. 64. 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
    65. 65. 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
    66. 66. 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
    67. 67. 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
    68. 68. 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
    69. 69. 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
    70. 70. 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
    71. 71. Queue : Création / UtilisationMonday, January 16, 12
    72. 72. Queue : Création / Utilisation • Main Queue : dispatch_queue_t main_queue = dispatch_get_main_queue();Monday, January 16, 12
    73. 73. 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
    74. 74. 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
    75. 75. Exemple : Calcul background + UI updateMonday, January 16, 12
    76. 76. 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
    77. 77. 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
    78. 78. 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
    79. 79. 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
    80. 80. Operation QueueMonday, January 16, 12
    81. 81. 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
    82. 82. Operation Queue Différences avec Dispatch QueueMonday, January 16, 12
    83. 83. 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
    84. 84. Operation Queue : exempleMonday, January 16, 12
    85. 85. Operation Queue : exemple • Application avec popup de login : user/password ==> plusieurs requêtes au lancement : une seule popupMonday, January 16, 12
    86. 86. Operation Queue Thread courant NSOp1 NSOp2 NSOp3 NSOp4 NSOp5 Thread 1 NSOperation Queue maxConcurrentOperation = 1Monday, January 16, 12
    87. 87. Operation Queue NSOp5 Thread courant NSOp4 NSOp3 NSOp2 NSOp1 Thread 1 NSOperation Queue maxConcurrentOperation = 1Monday, January 16, 12
    88. 88. Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOp1 NSOperation Queue maxConcurrentOperation = 1Monday, January 16, 12
    89. 89. Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOp1 executing NSOperation NSOp1 Queue maxConcurrentOperation = 1Monday, January 16, 12
    90. 90. Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    91. 91. Operation Queue Thread courant NSOp5 NSOp4 NSOp3 NSOp2 Thread 1 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    92. 92. Operation Queue Thread courant NSOp5 NSOp2 Thread 1 NSOp3 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    93. 93. Operation Queue Thread courant NSOp5 NSOp2 Thread 1 Thread 2 NSOp3 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    94. 94. Operation Queue Thread courant NSOp5 NSOp2 Thread 1 Thread 2 Thread 3 NSOp3 NSOp4 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    95. 95. 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
    96. 96. 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
    97. 97. Operation Queue Thread courant NSOp2 executing Thread 1 Thread 2 Thread 3 NSOp5 executing NSOp2 NSOp5 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    98. 98. Operation Queue Thread courant Thread 1 Thread 2 Thread 3 NSOp5 executing NSOp5 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    99. 99. Operation Queue Thread courant Thread 1 Thread 2 Thread 3 NSOperation Queue maxConcurrentOperation = 3Monday, January 16, 12
    100. 100. Operation Queue UtilisationMonday, January 16, 12
    101. 101. Operation Queue Utilisation @interface FSHttpRequest : NSOperation { }Monday, January 16, 12
    102. 102. Rappel NSUrl * url = [NSURL URLWithString:@"http://www.cocoaheads.fr"]; FSHttpRequest *request = [FSHttpRequest requestWithUrl:url]; [request setCompletionBlock:^ { }]; [request startRequest];Monday, January 16, 12
    103. 103. Operation Queue Utilisation @interface FSHttpRequest : NSOperation { }Monday, January 16, 12
    104. 104. Operation Queue Utilisation @interface FSHttpRequest : NSOperation { } @implementation FSHttpRequest - (void)startRequest:(NSURLRequest *)request { } @endMonday, January 16, 12
    105. 105. Operation Queue Utilisation @interface FSHttpRequest : NSOperation { } @implementation FSHttpRequest static NSOperationQueue *queue = nil; - (void)startRequest:(NSURLRequest *)request { } @endMonday, January 16, 12
    106. 106. 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
    107. 107. 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
    108. 108. 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
    109. 109. Operation Queue Ajouts de GCD : NSBlockOperationMonday, January 16, 12
    110. 110. 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
    111. 111. 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

    ×