fsp*_*rit 85 iphone core-data objective-c
我需要创建NSManagedObject实例,用它们做一些事情,然后将它们丢弃或存储到sqlite db.问题是,我无法创建NSManagedObject未连接的实例,NSManagedObjectContext这意味着在我决定不需要我的数据库中的某些对象后,我必须以某种方式清理.
为了解决这个问题,我使用相同的协调器创建了一个内存存储,并且我使用assignObject:toPersistentStore.Now 将临时对象放在那里,如何确保这些临时对象无法获取数据,我从中获取数据两个商店的上下文共同点?或者我是否必须为此类任务创建单独的上下文?
现在我正在考虑为内存存储创建单独的上下文.如何将对象从一个上下文移动到另一个上下文?只是使用[context insertObject:]?它在这个设置中可以正常工作吗?如果我从对象图中插入一个对象,整个图形是否也会插入到上下文中?
Mar*_*rra 144
注意:这个答案非常陈旧.查看完整历史记录的评论.我的建议已经改变,我不再建议使用无关联的NSManagedObject实例.我目前的建议是使用临时子NSManagedObjectContext实例.
原始答案
最简单的方法是创建NSManagedObject没有关联的实例NSManagedObjectContext.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:myMOC];
NSManagedObject *unassociatedObject = [[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
Run Code Online (Sandbox Code Playgroud)
然后当你想保存它时:
[myMOC insertObject:unassociatedObject];
NSError *error = nil;
if (![myMoc save:&error]) {
//Respond to the error
}
Run Code Online (Sandbox Code Playgroud)
rai*_*ade 39
iOS5提供了一个更简单的替代Mike Weller的答案.而是使用子 NSManagedObjectContext.它消除了通过NSNotificationCenter进行蹦床的需要
要创建子上下文:
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
childContext.parentContext = myMangedObjectContext;
Run Code Online (Sandbox Code Playgroud)
然后使用子上下文创建对象:
NSManagedObject *o = [NSEntityDescription insertNewObjectForEntityForName:@"MyObject" inManagedObjectContext:childContext];
Run Code Online (Sandbox Code Playgroud)
仅在保存子上下文时应用更改.所以放弃更改只是不保存.
关系仍有限制.即,您无法在其他上下文中创建与对象的关系.为了解决这个问题,请使用objectID来从子上下文中获取对象.例如.
NSManagedObjectID *mid = [myManagedObject objectID];
MyManagedObject *mySafeManagedObject = [childContext objectWithID:mid];
object.relationship=mySafeManagedObject;
Run Code Online (Sandbox Code Playgroud)
请注意,保存子上下文会将更改应用于父上下文.保存父上下文会保留更改.
有关完整说明,请参见wwdc 2012会话214.
实现此类事情的正确方法是使用新的托管对象上下文.您使用相同的持久性存储创建托管对象上下文:
NSManagedObjectContext *tempContext = [[[NSManagedObjectContext alloc] init] autorelease];
[tempContext setPersistentStore:[originalContext persistentStore]];
Run Code Online (Sandbox Code Playgroud)
然后你添加新对象,改变它们等.
当需要保存时,需要在tempContext上调用[tempContext save:...],并处理保存通知以将其合并到原始上下文中.要丢弃对象,只需释放此临时上下文并忘记它.
因此,当您保存临时上下文时,更改将持久保存到商店,您只需将这些更改返回到主上下文中:
/* Called when the temp context is saved */
- (void)tempContextSaved:(NSNotification *)notification {
/* Merge the changes into the original managed object context */
[originalContext mergeChangesFromContextDidSaveNotification:notification];
}
// Here's where we do the save itself
// Add the notification handler
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(tempContextSaved:)
name:NSManagedObjectContextDidSaveNotification
object:tempContext];
// Save
[tempContext save:NULL];
// Remove the handler again
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:tempContext];
Run Code Online (Sandbox Code Playgroud)
这也是您应该处理多线程核心数据操作的方式.每个线程一个上下文.
如果您需要从这个临时上下文访问现有对象(添加关系等),那么您需要使用对象的ID来获取这样的新实例:
NSManagedObject *objectInOriginalContext = ...;
NSManagedObject *objectInTemporaryContext = [tempContext objectWithID:[objectInOriginalContext objectID]];
Run Code Online (Sandbox Code Playgroud)
如果您尝试NSManagedObject在错误的上下文中使用,则在保存时会出现异常.
你所描述的正是NSManagedObjectContext它的用途.
您可以将托管对象上下文视为智能便笺簿.从持久性存储中获取对象时,将临时副本放在便笺簿上,它们形成对象图(或对象图的集合).然后,您可以根据需要修改这些对象.但是,除非您实际保存这些更改,否则持久存储仍保持不变.
这也支持了表示"暂存区"的托管对象上下文的想法 - 通常,您可以将托管对象放在便笺簿上,然后根据您的意愿编辑它们,最后提交更改或丢弃它们.
NSManagedObjectContexts设计为轻量级.您可以随意创建和丢弃它们 - 它是持久性存储协调器,它的依赖性很"重".单个持久性存储协调器可以具有与之关联的许多上下文.在旧的,过时的线程限制模型下,这意味着在每个上下文中设置相同的持久性存储协调器.今天,它意味着将嵌套上下文连接到与持久性存储协调器关联的根上下文.
在该上下文中创建上下文,创建和修改托管对象.如果要保留它们并传达这些更改,请保存上下文.否则丢弃它.
尝试创建独立于a的托管对象NSManagedObjectContext是在寻找麻烦.请记住,核心数据最终是对象图的变更跟踪机制.因此,托管对象实际上是托管对象上下文的一部分.上下文观察它们的生命周期,如果没有上下文,并非所有托管对象功能都能正常工作.
根据您对临时对象的使用情况,上述建议有一些注意事项.我的用例是我想创建一个临时对象并将其绑定到视图.当用户选择保存此对象时,我想设置与现有对象的关系并保存.我想这样做是为了避免创建一个临时对象来保存这些值.(是的,我可以等到用户保存然后抓取视图内容,但我将这些视图放在一个表中,并且执行此操作的逻辑不太优雅.)
临时对象的选项是:
1)(首选)在子上下文中创建临时对象.这不起作用,因为我将对象绑定到UI,我无法保证在子上下文中调用对象访问器.(我没有找到其他文件,所以我不得不假设.)
2)使用nil对象上下文创建临时对象.这不起作用并导致数据丢失/损坏.
我的解决方案:我通过使用nil对象上下文创建临时对象来解决这个问题但是当我保存对象时,而不是将其作为#2插入,我将其所有属性复制到我在主上下文中创建的新对象中.我在我的NSManagedObject子类中创建了一个名为cloneInto的支持方法:它允许我轻松地为任何对象复制属性和关系.
| 归档时间: |
|
| 查看次数: |
33485 次 |
| 最近记录: |