Работа с основными данными в многопоточном режиме, утечка памяти? - PullRequest
1 голос
/ 09 февраля 2012

ПОСТАНОВИЛИ

Я работаю над приложением core data с многопоточностью, в котором мне нужно иметь дело со многими документами.

Я выполняю вставку, удаление, обновление и т. Д. В основных данных, используя эти данные документа.

Поскольку мы имеем дело с огромным количеством данных, я использую отдельный NSManagedObjectContext для каждой операции потока (сохраняя основной контекст для mainThread).

Для удобного управления NSManagedObjectContext я установил контекст в словарь тем.

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

Но я обнаружил, что контекст полностью удаляется при выходе из потока (поскольку текущий поток убивает себя после своей работы, словарь потока также очищается).

Ниже приведен код для получения управляемогоObjectContext

-(NSManagedObjectContext*)managedObjectContext     {

    NSManagedObjectContext *context = nil;
    if ([NSThread isMainThread])    {
        if (!managedObjectContext) {
            context = [NSManagedObjectContext newContextForPersistentStoreCoordinator:[self persistentStoreCoordinator]];
                [self setManagedObjectContext:context];
        }

        context = managedObjectContext;
    } 
    else    {
        //find context for this thread.
        NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
        context = [threadDictionary objectForKey:kManagedObjectContextKey];
        if (!context)   {
            //create a new context for this thread.
            context = [NSManagedObjectContext newContextForPersistentStoreCoordinator:[self persistentStoreCoordinator]];
            [threadDictionary setObject:context forKey:kManagedObjectContextKey];
            [context setUndoManager:nil];

            //to start observing context through DidSaveNotification.
            [self startObserveContext:context];
        }
   }

    return context;
}

И инструмент, показывающий отсутствие утечек, показывает, когда я использовал только один / основной NSManagedObjectContext. Но это вызывает проблемы с памятью при работе с большими документами, поэтому мне нужен отдельный NSManagedObjectContext для каждой операции потока

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

Спасибо

Ответы [ 2 ]

0 голосов
/ 13 февраля 2012

Я изменил следующие модификации в моем коде

-(NSManagedObjectContext*)managedObjectContext     {

    NSManagedObjectContext *context = nil;
    if ([NSThread isMainThread])    {
        if (!managedObjectContext) {
            context = [NSManagedObjectContext newContextForPersistentStoreCoordinator:[self persistentStoreCoordinator]];
                [self setManagedObjectContext:context];
        }

        context = managedObjectContext;
    } 
    else    {
        //find context for this thread.
        NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
        context = [threadDictionary objectForKey:kManagedObjectContextKey];
        if (!context)   {
            //create a new context for this thread.
            context = [NSManagedObjectContext newContextForPersistentStoreCoordinator:[self persistentStoreCoordinator]];
           [context setUndoManager:nil];

            //to start observing context through DidSaveNotification.
            [self startObserveContext:context];
            [threadDictionary setObject:context forKey:kManagedObjectContextKey];
            [context release]
            context = nil;

return [threadDictionary objectForKey:kManagedObjectContextKey];
        }
   }

    return context;
}

Ранее [NSManagedObjectContext newContextForPersistentStoreCoordinator: [self persistentStoreCoordinator]]; метод возврата авто-релиза NSManagedObjectContext, я удалил авто-релиз,

и в методе запуска операции {} я добавил ..

Мой класс NSOperation

start {
.........
........
.......
 NSManagedObjectContext *currentContext = (NSManagedObjectContext *)[[[NSThread currentThread] threadDictionary] objectForKey:kManagedObjectContextKey];
    [currentContext reset];
    [[[NSThread currentThread] threadDictionary] removeObjectForKey:kManagedObjectContextKey];
    currentContext = nil;

}

после всех функций в начале (в конце запуска добавлены строки удаления контекста).

0 голосов
/ 09 февраля 2012

Вместо потоков и словарей почему бы не использовать блоки? Здесь есть хорошее объяснение: http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/

(я собирался опубликовать методы, которые я использую, но этот учебник намного лучше)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...