Вопрос по objective-c, concurrency, ios5 – Основные данные и параллелизм с использованием NSOperationQueues

3

После использования Instruments я обнаружил в моем коде место, которое очень долго работает и блокирует мой пользовательский интерфейс: большое количество выборок из Core Data (это часть процесса приема большого JSON-пакета и создания управляемых объектов, при этом убедившись, что что объекты не были продублированы).

Хотя мои намерения состоят в том, чтобы разбить этот запрос на более мелкие части и обработать их поочередно, это означает лишь то, что я буду распространять эти извлечения - я ожидаю, что результатом будет небольшое количество рывков в приложении вместо одного длинного сбоя.

Все, что я читал как в документах Apple, так и в Интернете на различных постах в блогах, указывает на то, что Core Data и параллелизм сродни улей улья. Итак, я робко сел, чтобы дать ему слово. колледж попробуй. Ниже приводится то, что я придумаю, и я был бы признателен, если бы кто-то более мудрый указал на любые ошибки, которые, я уверен, я написал.

Код, размещенный ниже, работает. То, что я прочитал, запугало меня тем, что я, безусловно, сделал что-то не так; Я чувствую, будто вытащил булавку из гранаты и просто жду, когда она неожиданно сработает!

NSBlockOperation *downloadAllObjectContainers = [NSBlockOperation blockOperationWithBlock:^{
    NSArray *containers = [webServiceAPI findAllObjectContainers];
}];

[downloadAllObjectContainers setCompletionBlock:^{

    NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [backgroundContext setPersistentStoreCoordinator:[_managedObjectContext persistentStoreCoordinator]];

    [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
                                                      object:backgroundContext
                                                       queue:[NSOperationQueue mainQueue]
                                                  usingBlock:^(NSNotification *note) {
                                                      [_managedObjectContext mergeChangesFromContextDidSaveNotification:note];
                                                  }];


        Builder *builder = [[Builder alloc] init];
        [builder setManagedObjectContext:backgroundContext];

        for (ObjectContainer *objCont in containers) {  // This is the long running piece, it's roughly O(N^2) yuck!
            [builder buildCoreDataObjectsFromContainer:objCont];
        }

    NSError *backgroundContextSaveError = nil;
    if ([backgroundContext hasChanges]) {
        [backgroundContext save:&backgroundContextSaveError];
    }
}];

NSOperationQueue *background = [[NSOperationQueue alloc] init];
[background addOperation:downloadAllObjectContainers];

Ваш Ответ

2   ответа
0

Concurrency

Параллельность - это возможность работать с данными более чем в одной очереди одновременно. Если вы решите использовать параллелизм с Core Data, вам также необходимо рассмотреть среду приложения. В большинстве случаев AppKit и UIKit не являются поточно-ориентированными. В частности, в OS X привязки и контроллеры Какао не являются потокобезопаснымиОсновные данные, многопоточность и основной поток

6

вы должны делать это для iOS5, вам не нужно проходить через все проблемы создания контекста в фоновом потоке и слияния его в основном потоке.

Все, что вам нужно, это создать контекст управляемого объекта с типом параллелизма NSPrivateQueueConcurrencyType в главном потоке и выполнить все операции с управляемыми объектами внутри блока, переданного методу managedObjectContext: executeBlock.

Я рекомендую вам взглянуть наWWDC2011 session 303 - What's New in Core Data on iOS. Also, take a look at Примечания к выпуску основных данных для iOS5.

Вот цитата из заметок о выпуске:

NSManagedObjectContext now provides structured support for concurrent operations. When you create a managed object context using initWithConcurrencyType:, you have three options for its thread (queue) association

Confinement (NSConfinementConcurrencyType).

This is the default. You promise that context will not be used by any thread other than the one on which you created it. (This is exactly the same threading requirement that you've used in previous releases.)

Private queue (NSPrivateQueueConcurrencyType).

The context creates and manages a private queue. Instead of you creating and managing a thread or queue with which a context is associated, here the context owns the queue and manages all the details for you (provided that you use the block-based methods as described below).

Main queue (NSMainQueueConcurrencyType).

The context is associated with the main queue, and as such is tied into the application’s event loop, but it is otherwise similar to a private queue-based context. You use this queue type for contexts linked to controllers and UI objects that are required to be used only on the main thread.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded edelaney05

Похожие вопросы