57 votes

Récupération d'arrière-plan de données de base via le nouveau type NSPrivateQueueConcurrencyType

Est-il vraiment si simple maintenant dans iOS5?

J'ai utilisé pour réaliser un fond d'extraction à l'aide de ce code dans mon AppDelegate:

dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL);
dispatch_async(downloadQueue, ^{
        self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.managedObjectContext];
        [self.myDownloadClass download];
    });

dispatch_release(downloadQueue);

Mon téléchargement de la classe effectue une NSURLConnection pour aller chercher des données XML, utilise NSXMLParser pour analyser les données, puis les mises à jour d'un schéma complexe dans la base de données. Je serais toujours basculer vers le thread principal à fait de mise à jour de la base de données. Le code désordre, avec beaucoup d'appels à dispatch_sync(dispatch_get_main_queue()....

Mon nouveau code ressemble à ceci:

NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:self.managedObjectContext];

[child performBlock:^{
    self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child];
    [self.myDownloadClass download];
    }];

avec un petit changement à un autre code dans mon AppDelegate pour définir le modèle parent du contexte de l'objet type de NSMainQueueConcurrencyType:

- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}

Il semble très bien fonctionner. L'ensemble du processus de mise à jour s'exécute toujours dans un thread séparé, mais je n'ai pas de créer un thread. Est comme de la magie.

N'oubliez pas si vous voulez enregistrer vos modifications dans le noyau physique des fichiers de données, vous devez appeler la méthode save: sur le contexte parent.

Je n'ai pas vraiment poser une question ici. Je suis l'affichage de cette sorte qu'il aide les autres, parce que tout ce que j'ai trouvé lors de la recherche de la nouvelle iOS5 géré contexte de l'objet de méthodes de seulement donné à haut niveau de détails sans que des exemples de code Et toutes les autres recherches pour la récupération de base de données en arrière-plan sont vieux, parfois très anciennes, et de discuter de la façon de faire de la pré-iOS5.

2voto

Scott Corscadden Points 2009

Oui, c’est aussi simple que cela (sous iOS 5.0). Pour la compatibilité iOS 4, les obstacles précédents restent, mais la documentation n’est pas trop mauvaise sur le confinement des threads. Peut-être devriez-vous ajouter ceci à une section wiki?

0voto

Joris Kluivers Points 5311

J'essaie de comprendre comment cette nouvelle API est mis en œuvre. Mon modèle habituel pour multithread l'essentiel des données est quelque chose comme ceci:

Habituellement, dans un NSOperation mais simplifié à l'aide de dispatch_async dans cet exemple:

dispatch_queue_t coredata_queue; // some static queue

dispatch_async(coredata_queue, ^() {
    // get a new context for this thread, based on common persistent coordinator
    NSManagedObjectContext *context = [[MyModelSingleton model] threadedContext];

    // do something expensive

    NSError *error = nil;
    BOOL success = [context save:&error];
    if (!success) {
        // the usual.
    }

    // callback on mainthread using dispatch_get_main_queue();
});

Alors le thread principal va répondre par la mise à jour de l'INTERFACE utilisateur basée sur NSManagedObjectContextDidSaveNotification de fusionner le contexte principal.

La nouvelle API semble être un wrapper autour de ce modèle, où l' child contexte dirait qu'il prend juste la persistance de la coordonnatrice de son parent pour créer un nouveau contexte. Et en spécifiant NSPrivateQueueConcurrencyType sur init sera assurez-vous que l' performBlock paramètre est exécuté sur la file d'attente privée.

La nouvelle API ne semble pas être beaucoup moins de code à taper. Les avantages par rapport à la "traditionnelle" threading?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X