iphone – 在获取PantantID之后,核心数据无法充满对象的错误

栏目: 数据库 · 发布时间: 6年前

内容简介:http://stackoverflow.com/questions/11321717/core-data-could-not-fullfil-fault-for-object-after-obtainpermanantids

我从网络服务器获取数据,在一个名为backgroundMOC的子私人背景上下文中处理它.它是一个与主UI相关联的mainMOC的子进程,因此在backgroundMOC上保存触发UI更改. mainMOC是一个masterMOC的子代,它是一个与持久存储相关联的私有后台队列,所以保存在主节点上保存到磁盘.

我现在所做的是接收数据,在backgroundMOC上创建新对象,然后保存backgroundMOC(以便UI更新),保存mainMOC(使我几乎可以保存到磁盘),并保存masterMOC(以便我可以最终写入磁盘).问题是当对象通过获取的结果控制器出现在UI中时,objectId仍然是暂时的.

这会导致重复行问题,如果我从服务器收到相同的数据(意外),我的backgroundMOC不知道这个对象已经存在,因为它没有被分配一个永久的id,所以它创建另一个对象.当我重新启动应用程序时,重复的对象消失,所以我知道这只是一个id映射的问题.

所以我以为我可以试试

[backgroundMOC obtainPermanentIDsForObjects:backgroundMOC.registeredObjects.allObjects error:nil];

在保存之前(我也保存后尝试过).但是,由于某种原因,调用此行会抛出异常:

CoreData could not fulfill a fault for...

如果您有任何提示可能导致我正确的方向,请分享.谢谢

编辑:好的,最初我在backgroundMOC上调用getsPermanentIDsForObjects,它是mainMOC的一个小孩,它是masterMOC的一个子代.我切换它,以便在mainMOC上获得ids,并解决了我所有的问题(现在).我从来不会在child context上调用getsPermIds吗?

这是一个已知的错误(嵌套的上下文在保存新对象时不会获得永久性的ID)可能会在即将发布的版本中被修复

你应该可以要求永久性的ID,但你应该只是要求他们已经插入的对象.

[moc obtainPermanentIDsForObjects:moc.insertedObjects.allObjects error:0];

您必须在保存MOC之前执行此操作,因为如果在不获取永久ID的情况下保存,则临时ID将传播到父上下文.例如,在您保存到mainMoc的情况下,然后获取IDS,backgroundMOC仍然具有临时ID,因此从未来的存储将创建重复的数据.

请注意,获取永久ID一直到数据库,但是如果您在主MOC的MOC中执行此操作,则在发生这种情况时,您不应该阻止主线程.

所以,在你的最低级别的MOC中,你应该有效地拥有这样的东西(当然有适当的错误处理)…

[backgroundMoc performBlock:^{
    [backgroundMoc obtainPermanentIDsForObjects:backgroundMoc.insertedObjects.allObjects error:0];
    [backgroundMoc save:0];
    [mainMoc performBlock:^{
       [mainMoc save:0];
        [masterMoc performBlock:^{
            [masterMoc save:0];
        }];
    }];
}];

还有一些其他可以玩的游戏,如果你愿意的话.

提供类似于NSManagedObject的类别…

@implementation NSManagedObject (initWithPermanentID)
- (id)initWithEntity:(NSEntityDescription *)entity insertWithPermanentIDIntoManagedObjectContext:(NSManagedObjectContext *)context {
    if (self = [self initWithEntity:entity insertIntoManagedObjectContext:context]) {
        NSError *error = nil;
        if (![context obtainPermanentIDsForObjects:@[self] error:&error]) {
            @throw [NSException exceptionWithName:@"CoreData Error" reason:error.localizedDescription userInfo:error.userInfo];
        }
    }
    return self;
}

+ (NSArray*)createMultipleObjects:(NSUInteger)count withEntity:(NSEntityDescription *)entity inManagedObjectContext:(NSManagedObjectContext *)context {
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:count];
    for (NSUInteger i = 0; i < count; ++i) {
        [array addObject:[[self alloc] initWithEntity:entity insertIntoManagedObjectContext:context]];
    }
    NSError *error = nil;
    if (![context obtainPermanentIDsForObjects:array error:&error]) {
        @throw [NSException exceptionWithName:@"CoreData Error" reason:error.localizedDescription userInfo:error.userInfo];
    }
    return array;
}
@end

现在,在第一个,你正在付钱进入数据库,并为每个创建的实体创建一个ID,但是并不是那么多,而是发生在一个后台线程中,每个下降都很短

哦,这不是最好的,但它提供了有用的.此外,第二个创建相同对象的多个,并同时抓取它们的永久ID.

您还可以使用直接连接到PSC的MOC,并观察DidChange事件,但是与旧方式相同.

不幸的是,你不能有一个单独的MOC只是做出持久化ID请求并传递ObjectID,虽然你可以有一个单独的MOC在DB中创建原型对象,并给你的ObjectID.

一个原型工厂是一个相当普遍的模式,如果你走这条路线,当最终的错误修复到这里时,很容易做一个小的改变.

编辑

响应斯文

如果您正在创建新的复杂图形,则需要在创建后立即获取永久性ID.要减少对商店的命中次数,您应该全部创建它们,然后一次获取ID,然后开始挂起它们.

老实说,所有这一切都是为了解决目前存在的错误,这些bug值得为小型到中型的更新而努力.当错误被修复时,您的代码将是一样的(无需获取).所以,我建议这种方法进行较小的进口.

如果您正在进行大规模更新,建议您使用“旧”方法.创建一个直接连接到PSC的MOC.在那里进行所有的更改,并让您的“活”上下文只是从那些DidSave通知合并.

最后,对数据库的永久ID影响.丢弃MOC是可以的.磁盘被击中,元数据被更改,但对象不被保留.

老实说,我没有做一个大的考验,看看是否有空的空间,但是,所以你可能想这样做,并与我一起回来.

查看磁盘上的实际数据库文件大小,然后创建10000个对象,然后获取持久性ID,释放MOC,再次查看大小.

如果有影响,您可以尝试删除对象,或者在大型更新后在数据库上运行真空,以查看是否有效.

如果要创建很多可能会丢弃的对象,那么就不需要打数据库了.您可能只想直接附加到PSC并使用旧的忠实通知.

http://stackoverflow.com/questions/11321717/core-data-could-not-fullfil-fault-for-object-after-obtainpermanantids


以上所述就是小编给大家介绍的《iphone – 在获取PantantID之后,核心数据无法充满对象的错误》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Python语言程序设计

Python语言程序设计

(美)Y. Daniel Liang / 机械工业出版社 / 2013-3 / 79.00元

本书保持了Liang博士系列丛书中一贯的、标志性的教与学的哲学:以实例教,由实践学。书中采用了他所提出的已经经过实践检验的“基础先行”的方法,即在定义类之前,首先使用清晰简明的语言介绍基本程序设计概念,如选择语句、循环和函数;在介绍面向对象程序设计和GUI编程之前,首先介绍基本逻辑和程序设计概念。书中除了给出一些以游戏和数学为主的典型实例外,还在每章的开始使用简单的图形给出一两个例子,以激发学生的......一起来看看 《Python语言程序设计》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器