如何删除为编辑目的而创建的临时NSManagedObjectContext

时间:2012-08-31 14:22:49

标签: objective-c core-data nsmanagedobjectcontext

在iOS COreData应用程序中,我尝试了仅用于编辑对象的临时上下文。

我放弃了iOS 5引入的parentContext,因为它有错误,所以它只是一个普通的上下文,带有通常的保存通知机制,可以与主上下文合并。

这似乎有效,但我不确定一点:

我有一个为我构建上下文的工厂,而不是从控制器传递到控制器。临时上下文仅用于编辑目的,因为我不是一直在编辑实体,我的理解(也许是错误的)是,一旦工作完成就必须将其删除以释放资源。

那么要重新确定,如何删除临时上下文?或者是否需要留下来以便以后重复使用?

2 个答案:

答案 0 :(得分:0)

如果您使用ARC,您所要做的就是确保没有任何内容引用MOC。换句话说,如果你在某处保留一个指针,将其设置为nil。否则,当您停止引用MOC时,MOC应该足够容易销毁。

确保......的几种简单方法。

  1. 在乐器中,跟踪MOC对象以查看它们何时是alloc / dealloc。

  2. 子类NSManagedObjectContext并且只是覆盖init / dealloc - 确保调用super - 除了dealloc - 在ARC中不起作用。然后你可以追踪它

  3. 在 - [NSManagedObjectContext dealloc]设置断点并看到它消失

  4. 添加一个具有dealloc的关联对象(通过objc_setAssociatedObject),以便您可以看到何时取消分配MOC

  5. 设置一个__weak引用到MOC并观察它为零

  6. 许多其他选择......

  7. 最重要的是,有很多方法可以“跟踪”你的MOC被摧毁(或不是)。

    如果你正在使用ARC,你所要做的就是确保没有其他物体能够引用你的MOC,它会像所有其他物体一样进入日落。

    我的#1建议是我唯一按优先顺序排列的建议。如果你已经知道如何使用乐器,这将是一块蛋糕。

    如果您不知道如何使用乐器,那么您肯定应该使用选项#1,因为我不知道在Apple的平台上开发一个更有价值的开发工具(编译器本身除外)。

    - 当然,不使用ARC时同样适用 - 但你必须手动获取refcount资料。

答案 1 :(得分:0)

我编写了这个简短的代码,负责将上下文更改传播到其他上下文:

假设:

@property (nonatomic, strong) NSDictionary* threadsDictionary;

以下是如何获取托管对象(每个线程):

- (NSManagedObjectContext *) managedObjectContextForThread {

// Per thread, give one back
NSString* threadName = [NSString stringWithFormat:@"%d",[NSThread currentThread].hash];

NSManagedObjectContext * existingContext = [self.threadsDictionary objectForKey:threadName];
if (existingContext==nil){
    existingContext = [[NSManagedObjectContext alloc] init];
    [existingContext setPersistentStoreCoordinator: [self persistentStoreCoordinator]];
    [self.threadsDictionary setValue:existingContext forKey:threadName];
}

return existingContext;

}

在全局管理器的init方法中的某个时刻(我使用了单例):

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(backgroundContextDidSave:)                                                    name:NSManagedObjectContextDidSaveNotification                                                   object:nil];

然后接收保存通知并传播到所有其他托管上下文对象:

- (void)backgroundContextDidSave:(NSNotification *)notification {
    /* Make sure we're on the main thread when updating the main context */
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
                               withObject:notification
                            waitUntilDone:NO];
        return;
    }

    /* merge in the changes to the main context */
    for (NSManagedObjectContext* context in [self.threadsDictionary allValues]){
            [context mergeChangesFromContextDidSaveNotification:notification];
    }
}

(为清楚起见,删除了其他一些方法)