NSURLSession Threads: Suivi de plusieurs téléchargements en arrière-plan
Je suis donc la création de mon téléchargement sur le thread principal
NSURLRequest *request = [NSURLRequest requestWithURL:download.URL];
NSURLSessionDownloadTask *downloadTask = [self.downloadSession downloadTaskWithRequest:request];
[downloadTask resume];
et en ajoutant le NSManagedContextID associés avec le téléchargement d'un NSMutableDictionary,
donc, je peux la récupérer plus tard dans la délégué rappels
[self.downloads setObject:[download objectID] forKey:[NSNumber numberWithInteger:downloadTask.taskIdentifier]];
Mon self.downloadSession
ci-dessus est configuré comme ceci
- (NSURLSession *)backgroundSession
{
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.test.backgroundSession"];
configuration.discretionary = YES;
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
});
return session;
}
Mon problème est le délégué rappels semblent être appelée sur des threads différents
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
NSManagedObjectID *downloadID = [self.downloads objectForKey:[NSNumber numberWithInteger:downloadTask.taskIdentifier]];
double progress = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:downloadID,@"download",[NSNumber numberWithDouble:progress],@"progress", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"DownloadProgress" object:nil userInfo:userInfo];
}
Donc, lorsque j'accède à l'autonomie.téléchargements pour obtenir le bon objectID, je suis tout à fait accéder à la NSMutableDictionary à partir d'un autre thread que celui qu'il a été créé, et je crois NSMutableDictionary n'est pas thread-safe. Alors, quelle est la meilleure solution pour cela, j'ai pu servir à quelque chose comme ceci
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
lors de la déclaration de la session, définissez le délégué de la file d'attente à la mainQueue qui permet à tous les délégués d'être appelé sur le thread principal, mais je tiens à garder tous les rappels sur un thread d'arrière-plan si possible
Ce sujet de la manipulation avec
NSMutableArray
et NSObject
'modèle comme expliqué dans ce tutoriel?OriginalL'auteur Andrew | 2013-09-22
Vous devez vous connecter pour publier un commentaire.
Dans votre exemple, qui n'est pas un problème, puisque votre dictionnaire est remis au système de la notification et n'est pas utilisé par le fonctionnement de la file d'attente fil à nouveau. Fil de sécurité est seulement un problème lorsqu'un objet est potentiellement accessible à partir de plusieurs threads en même temps.
Si votre dict serait un iVar vous devriez le faire de cette façon:
Créer votre propre file d'attente comme ce
Puis de planifier tous les Accès à votre dictionnaire sur cette file d'attente, comme ceci par exemple:
Et bien sûr utiliser cette file d'attente pour votre URLSesson délégation:
Depuis cette file d'attente est configuré comme une série de file d'attente, il y aura toujours un thread accès au dict en arrière-plan.
Prendre soin lorsque vous calculez quelque chose avec le dict de l'information. Vous disposez pour ce faire de cette file d'attente. Toutefois, vous pouvez mettre le résultat de votre calcul sur un autre file d'attente/thread, par exemple pour mettre à jour l'INTERFACE utilisateur sur le thread principal.
Je pense que pour la publication d'une notification vous n'avez pas à utiliser ce modèle, parce que le système gère l'enfilage correctement. Mais pour être sauver, vous devez vérifier cela.
Ce sujet de la manipulation avec
NSMutableArray
etNSObject
'modèle comme expliqué dans ce tutoriel?OriginalL'auteur sofacoder
Vous pouvez utiliser un PGCD de série de la file d'attente pour s'assurer qu'un délégué est en cours d'exécution simultanément.
Vous pouvez déclarer la file d'attente comme une variable d'instance de votre classe et de l'initialiser dans la méthode init, comme ceci:
...
et dans votre délégué de la méthode, il suffit de le faire exécuter dans cette file d'attente:
De cette façon, bien que chaque délégué a appelé à son sujet, il y a seulement de leur accès à l'autonomie.téléchargements en une seule fois, et vous pouvez les garder dans des threads séparés.
Depuis il a les messages de notification, il serait plus intelligent d'envelopper le tout dans l'expédition sur le thread principal.
OriginalL'auteur Jose Servet