0

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

由于存在错误,我丢弃了 iOS 5 引入的 parentContext,所以它只是一个普通的上下文,具有通常的保存通知机制,用于与主上下文合并。

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

我有一个为我构建上下文的工厂,而不是从控制器传递到控制器。临时上下文仅用于编辑目的,并且因为我不是一直在编辑实体,所以我的理解(可能是错误的)是必须在工作完成后立即删除它以释放资源。

所以重新假设,如何删除临时上下文?还是需要保留以供以后重用?

4

2 回答 2

0

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

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

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

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

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

  4. 添加具有 dealloc 的关联对象(通过objc_setAssociatedObject),以便您可以查看 MOC 何时被释放

  5. 设置对 MOC 的 __weak 引用并观察它变为 nil

  6. 许多其他选择...

底线是有很多方法可以“跟踪”您的 MOC 被破坏(或不被破坏)。

如果您使用 ARC,您所要做的就是确保没有其他对象持有对您的 MOC 的引用,并且它会像所有其他对象一样消失在日落中。

我的 #1 建议是我唯一按偏好订购的建议。如果您已经知道如何使用 Instruments,这将是小菜一碟。

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

-- 当然,在不使用 ARC 时同样适用 -- 但您必须手动获取正确的引用计数。

于 2012-08-31T15:17:34.993 回答
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];
    }
}

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

于 2012-08-31T15:18:09.283 回答