Modèle GCD pour l'access aux ressources partagées + mise à jour de l'interface user?

gens! J'implémente un cache partagé dans mon application. L'idée est d'get datatables mises en cache du Web en arrière-plan, puis de mettre à jour le cache et l'interface user avec datatables nouvellement récupérées. L'astuce est bien sûr d'assurer la security des threads, puisque le thread principal utilisera continuellement le cache. Je ne veux pas modifier le cache de quelque façon que ce soit pendant que quelqu'un d'autre pourrait l'utiliser.

Je crois comprendre qu'utiliser @synchronized pour verrouiller l'access à une ressource partagée n'est pas l'approche la plus élégante d'ObjectiveC en raison de son piégeage dans le kernel et donc de son ralentissement. Je continue à lire que l'utilisation de GCD à la place est une excellente alternative (ignorons son cousin NSOperation pour le moment), et j'aimerais savoir quel serait un bon model pour ma situation. Voici un exemple de code:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // download the data in a background thread dispatch_async(queue, ^{ CacheData *data = [Downloader getLatestData]; // use the downloaded data in the main thread dispatch_sync(dispatch_get_main_queue(), ^{ [AppCache updateCache:data]; [[NSNotificationCenter defaultCenter] postNotificationName:@"CacheUpdated" object:nil]; }); }); 
  1. Est-ce que cela ferait vraiment ce que je pense et, dans l'affirmative, est-ce la façon la plus propre d'aborder ce genre de situation aujourd'hui? Il y a un article de blog qui est assez proche de ce dont je parle, mais je voulais aussi vérifier avec vous.
  2. Je pense que tant que je n'ai jamais access partagé la ressource partagée sur le même thread / queue (principal dans mon cas) et seulement mettre à jour l'interface user sur le principal, alors je vais effectivement atteindre la security des threads. Est-ce exact?

Merci!

Oui. D'autres considérations mises à part, au lieu de déplacer le travail de lecture / écriture sur le thread principal, pensez à utiliser une queue privée.

 dispatch_queue_t readwritequeue; readwritequeue = dispatch_queue_create("com.myApp.cacheAccessQueue", NULL); 

Ensuite, mettez à jour votre class AppCache:

 - (void)updateCache:(id)data { dispatch_sync(readwritequeue, ^{ ... code to set data ... }); } - (id)fetchData:... { __block id data = nil; dispatch_sync(readwritequeue, ^{ data = ... code to fetch data ...}); return data; } 

Ensuite, mettez à jour votre code original:

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // download the data in a background thread dispatch_async(queue, ^{ CacheData *data = [Downloader getLatestData]; **[AppCache updateCache:data];** // use the downloaded data in the main thread dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:@"CacheUpdated" object:nil]; }); }); 

Si vous requestz à 100 développeurs ici est la façon la plus élégante de le faire, vous obtiendrez au less 100 réponses différentes (peut-être plus!)

Ce que je fais, et ce qui fonctionne bien pour moi, c'est d'avoir une class singleton qui fait ma gestion d'image. J'utilise datatables de base et enregistre les vignettes directement dans le magasin, mais j'utilise le système de files et une URL dans datatables de base pour les «gros» files. Les données de base sont configurées pour utiliser la nouvelle interface basée sur les blocs afin de pouvoir effectuer tout son travail sur un thread privé géré par lui-même.

Les URL d'images possibles sont enregistrées avec un tag sur le fil principal. D'autres classs peuvent requestr l'image pour cette balise. Si l'image n'est pas là, nil est returnné, mais cette class définit un fetchingFlag, utilise une NSOperation simultanée couplée à un NSURLConnection pour récupérer l'image, quand elle l'obtient, elle envoie un message au singleton sur son thread avec datatables d'image reçues. méthode pour get ce message utilise '[moc performBlock: …]' (pas d'attente) pour le traiter.

Lorsque les images sont finalement ajoutées au référentiel, le microcontroller envoie une notification dans la queue principale avec l'label d'image reçue. Les classs qui voulaient l'image peuvent l'écouter, et lorsqu'elles l'obtiennent (sur le fil principal), elles peuvent alors requestr de nouveau au moc l'image, qui est évidemment là.