多线程核心数据操作,内存泄漏?

时间:2012-02-09 12:22:35

标签: iphone ios core-data memory-leaks nsmanagedobjectcontext

分辨

我正在使用多线程操作的core data应用程序,我需要处理许多文档。

我正在使用这些文档详细信息在核心数据中执行插入,删除,更新等。

由于处理大量数据,我为每个线程操作使用单独的NSManagedObjectContext。(保留mainThread的主上下文)。

为方便NSManagedObjectContext管理,我将上下文设置为线程字典。

使用此方法我没有任何关键内存松散,但是当我运行xcode instrument leaks工具时,它显示了与NSManagedObjectContext相关的泄漏对象的数量。

但是我发现当线程退出时上下文完全被删除了。(因为当前线程在其操作后自杀,线程字典也被清除)。

下面给出了获取managedObjectContext的代码

-(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 :(得分:0)

为什么不使用块而不是线程和线程词典?这里有一个很好的解释:http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/

(我即将发布我使用的方法,但该教程要好得多)

答案 1 :(得分:0)

我在代码中更改了以下修改

-(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;
}

Prevoulsy [NSManagedObjectContext newContextForPersistentStoreCoordinator:[self persistentStoreCoordinator]];方法返回自动释放的NSManagedObjectContext,我删除了自动释放,

并且在操作start {}方法中,我添加了..

我的NSOperation课程

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

}

在开始所有函数之后(开始添加上下文删除行的结束)。