我们一直在尝试调试Core Data多上下文/线程问题,其中将Core Data保存通知合并到我们的主线程NSManagedObjectContext中偶尔会使应用程序崩溃.这导致约2%的应用会话崩溃,我们对如何解决这个问题感到茫然.我们非常感谢任何可能导致此次崩溃的指导或一般建议.
我们有一个Core Data设置,如下所示:
注意这是从[MagicalRecord setupAutoMigratingCoreDataStack]创建的Magical Record v2.3中的默认核心数据堆栈
这是我们的应用程序崩溃的情况:
NSManagedObject在根节省上下文中将JSON解析为s(一些新实体,一些更新的实体)NSManagedObjectContextDidSaveNotification由Core Data广播.主队列上的默认上下文观察它并mergeChangesFromContextDidSaveNotification:使用NSDictionary主线程上的更改进行调用.objectID被发送到无效对象时崩溃(很可能NSManagedObject已被解除分配).这是在私人实施中发生的,NSManagedObjectContext mergeChangesFromContextDidSaveNotification:所以我们不可能看到这里出了什么问题; 在这一点上我们只能告诉我们一个应该存在的对象.

这仅发生在Core Data保存的一小部分上,表明这可能不是我们的Core Data→API堆栈的根本缺陷.此外,没有迹象表明上下文更改中的更改(插入/更新/删除)的大小或类型对崩溃的可能性有任何影响.
core-data objective-c nsmanagedobjectcontext ios magicalrecord
如何更新子托管对象上下文,以便它与父级具有相同的数据?
据我所知,在储蓄时,孩子只走了一步,即父母.然而,当获取提取总是非常深入到父和持久存储.所以我希望事情会是一样的.
但事实并非如此.
我有一个托管对象上下文,它是所有其他托管对象上下文的父级.
一个孩子改变数据并保存.父母也改变了.我在父进程上执行executeFetchRequest,我看到数据发生了变化.
但是,父母的一些孩子仍然使用旧数据.相同的对象id相同的数据.不知何故,该物业的价值保持不变.
如何告诉孩子从父母那里重新加载新数据?
更确切地说
说P是父母
说它有C1 C2 C3作为孩子
然后C1更改数据并提交.更改将传播到P.但是,在C2和C3处执行executeFetchRequest仍会显示旧数据.
是什么赋予了?
例如,当我检查imageBlob属性时,这就是我得到的:
儿童:
2013-02-05 13:57:42.865 BadgerNew[78801:c07] imageBlob: <UIImage: 0x89c3c50>
2013-02-05 13:57:42.866 BadgerNew[78801:c07] imageBlob: <null>
2013-02-05 13:57:42.866 BadgerNew[78801:c07] imageBlob: <null>
2013-02-05 13:57:42.866 BadgerNew[78801:c07] imageBlob: <null>
Run Code Online (Sandbox Code Playgroud)
家长:
2013-02-05 13:57:42.868 BadgerNew[78801:c07] imageBlob: <UIImage: 0x114af650>
2013-02-05 13:57:42.868 BadgerNew[78801:c07] imageBlob: <UIImage: 0x8e492e0>
2013-02-05 13:57:42.868 BadgerNew[78801:c07] imageBlob: <UIImage: 0x114c79b0>
2013-02-05 13:57:42.869 BadgerNew[78801:c07] imageBlob: <UIImage: 0xa8c76e0>
Run Code Online (Sandbox Code Playgroud)
这是一个更全面的版本,为什么我记下moc,父moc,blob,URL和对象ID.儿童:
特别是我希望mainqueue managedobject上下文是父节点的另一个子节点,而不是所有其他managedObjectContext的父节点.另一方面,我还希望mainQueue Managed对象上下文具有uptodate信息.我想知道标准解决方案是什么.
我的一些用户在执行保存时遇到CoreData错误.我无法在网上找到有关此错误的任何信息或如何表示堆栈跟踪.
错误消息是attempt to recursively call -save: on the context aborted, stack trace,下面有完整的错误消息.
任何人都有任何关于如何弄清楚出了什么问题的提示或想法?
Error Domain=NSCocoaErrorDomain Code=132001 "(null)" UserInfo={message=attempt to recursively call -save: on the context aborted, stack trace=(
0 CoreData 0x0000000188cbe70c + 164
1 Primetime 0x0000000100077ea4 Primetime + 130724
2 Primetime 0x00000001000ae988 Primetime + 354696
3 Primetime 0x0000000100081674 Primetime + 169588
4 Primetime 0x00000001000802ac Primetime + 164524
5 CoreData 0x0000000188d8bbd4 + 4568
6 CoreData 0x0000000188d8a9ec + 124
7 CoreFoundation 0x00000001869ac24c + 20
8 CoreFoundation 0x00000001869ab950 + 400
9 …Run Code Online (Sandbox Code Playgroud) 我有一个很好的工作iPhone应用程序,适用于核心数据.我使用NSFetchedResultsController/NSManagedObjectContext,如各种教程中所述.
现在我想扩展我的应用程序并添加更多功能.我需要建立一个数组,其中的对象具有来自我的数据的信息.
我不知何故需要获取我在上下文中拥有的所有数据的列表.
我想我可以采用类似于获取UITableView数据的方法.
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
Run Code Online (Sandbox Code Playgroud)
这个失败了,因为我确实有多个部分.现在我可以浏览所有部分并使用我自己的IndexPath来访问我的数据:
MyData *info = [_fetchedResultsController objectAtIndexPath:indexPath];
Run Code Online (Sandbox Code Playgroud)
但我认为还有另一种方法我还没有找到,我希望有人可以帮助我.
非常感谢.
我正在研究一些使用NSOperation导入数据的代码.我希望用户能够撤消NSManagedObject导入操作期间创建的实例.
据我所知,NSManagedObjectContext -undoManager对于从主线程执行的任何操作都是不可能的.从" 使用线程限制到支持并发"的" 核心数据编程指南"部分,我们有以下两个条件:
- 应该在托管对象上下文之间传递objectID(在不同的线程上)
- 在使用objectID之前,必须将托管对象保存在上下文中.
这是有道理的,因为托管对象需要在共享之前从私有存储(NSManagedObjectContext)移动到公共存储(NSPersistentStore).
不幸的是,该-save:消息还会导致撤消堆栈中的任何托管对象被删除.从同一指南的 内存管理使用核心数据部分:
具有挂起更改(插入,删除或更新)的托管对象将由其上下文保留,直到其上下文发送save:,reset,rollback或dealloc消息,或者相应数量的撤消以撤消更改.
我已经尝试了几个方法来解决这个限制,一切最终都会导致主要线程上发生的大量工作(以及旋转的沙滩球.)任何使用撤消处理主线程创建的对象的线索都会非常非常感激.
-
已提交增强型雷达:rdar:// problem/8977725
cocoa core-data objective-c nsoperation nsmanagedobjectcontext
我有一个主要的NSManagedObjectContext,它是在appDelegate中创建的.
知道,我正在使用另一个NSManagedObjectContext来编辑/添加新对象而不影响主NSManagedObjectContext,直到我保存它们.
当我保存第二个NSManagedObjectContext时,更改不会反映在主NSManagedObjectContext中,但如果我从模拟器打开.sqlite数据库,则更改已正确保存到.sqlite数据库中.无论我是否再次获取数据,即使我创建了第三个NSManagedObjectContext,我也看不到第二个NSManagedObjectContext的更改,但此时这些更改都在磁盘上...
如果我退出并打开应用程序,则所有更改都在那里.
是什么导致主NSManagedObjectContext不能看到商店的新变化?
在此方法之前,我使用相同的NSManagedObjectContext和undoManager,但我想将其更改为使用两个不同的NSManagedObjectContext.
谢谢,
米
NSError* error = nil;
if ([managedObjectContext hasChanges]) {
NSLog(@"This new object has changes");
}
if (![managedObjectContext save:&error]) {
NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0) {
for(NSError* detailedError in detailedErrors) {
NSLog(@" DetailedError: %@", [detailedError userInfo]);
}
}
else {
NSLog(@" %@", [error userInfo]);
}
}
Run Code Online (Sandbox Code Playgroud) 从NSManagedObjectContext内部 - 保存:我收到此消息:
断言失败:(_ Unwind_SjLj_Resume()无法返回),函数_Unwind_SjLj_Resume,文件/SourceCache/libunwind/libunwind-24.1/src/Unwind-sjlj.c,第326行.
程序收到信号:"SIGABRT".
警告:无法读取/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1(8C148)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib(未找到文件)的符号.
当我使用Run删除带有to-many的Experiment对象时,会发生这种情况,其中包含Sample,其中包含与Data一起使用的Sample.实验也有许多与页面有很多与显示,其中有许多运行.我提到这一点是为了指出图的周期性.这是一个简化的模型图:

实验用户与之交互的顶级实体.实验包含多个Run对象.运行是从特定时间开始并在稍后结束的数据集合.由于可以同时从多个源收集数据,因此每个Run的每个源都有一个Sample.实验包含数据,需要查看和交互此数据.因此,每个实验都有一些页面对象,每个页面包含一些显示(例如,图形,米).显示器配置为显示属于实验的运行的某个子集.因此,虽然实验可能包含数十个运行,但其中一个页面一次只会显示一些运行.Display实体维护此列表.显示不是视图.视图将引用Display对象并通知Display对象的更改.
我一直在使用删除规则,但现在已经切换到"无操作"删除规则以及所有这些类的-prepareForDeletion方法.这种变化没有任何区别.在这两种情况下,错误消息都是相同的.
有趣的是,当我重新启动应用程序时,所有标记为删除的对象都已被删除.
此外,如果实验没有运行对象,则删除工作没有发生.就此而言,从实验中删除单个Run也可以.
我希望有人见过这样的东西,可以提供有关导致这种情况的建议.或者,如果某人有关于如何获取iOS 4.2.1的libXcodeDebuggerSupport.dylib的建议,那么这可能也会有所帮助.
更新:我按照这里的建议,并能够让Xcode找到适用于iOS 4.2.1的libXcodeDebuggerSupport.dylib.但这对诊断问题毫无帮助 - 这种问题依然存在.
更新2:在阅读了一下并下载unwind-sjlj.c的版本之后,似乎我正在处理类似未捕获的异常.我不确定这对我有什么帮助......
更新3:感谢堪察加,我做了几天前我应该做的事情:打开"停止Objective-C Exceptions".这让我看到仍然保留了对已删除对象的引用 - 更糟糕的是,键值观察了已删除的对象.解决了这个固定的问题,我能够恢复使用删除规则而不是-prepareForDeletion方法.
//设置通知
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(dataChanged:)
name:NSManagedObjectContextDidSaveNotification
object:context];
Run Code Online (Sandbox Code Playgroud)
//后来
- (void)dataChanged:(NSNotification *)notification{
NSDictionary *info = notification.userInfo;
NSSet *insertedObjects = [info objectForKey:NSInsertedObjectsKey];
NSSet *deletedObjects = [info objectForKey:NSDeletedObjectsKey];
NSSet *updatedObjects = [info objectForKey:NSUpdatedObjectsKey];
Run Code Online (Sandbox Code Playgroud)
无论如何要从updatedObjects确定哪些字段实际更改了?
谢谢,迈克尔
我正在尝试CoreData在iosApplication中实现,现在我想从Entity获取所有记录MUSTHAFA
My NSManagedObjectedSubClass is MUSTAHFA
Run Code Online (Sandbox Code Playgroud)
MUSTHAFA.m
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface MUSTHAFA : NSManagedObject {
@private
}
@property (nonatomic, retain) NSString * FirstName;
@property (nonatomic, retain) NSNumber * Age;
@property (nonatomic, retain) NSString * Location;
@property (nonatomic, retain) NSString * LastName;
@end
#import "MUSTHAFA.h"
@implementation MUSTHAFA
@dynamic FirstName;
@dynamic Age;
@dynamic Location;
@dynamic LastName;
@end
Run Code Online (Sandbox Code Playgroud)
将记录添加到核心数据
-(void)AddRecordToCoreData{
//NSLog(@"______ ADD Core Data Implementaion");
MUSTHAFA *event = (MUSTHAFA *)[NSEntityDescription insertNewObjectForEntityForName:@"MUSTHAFA" inManagedObjectContext:managedObjectContext];
[event setLastName:@"JOHN"];
[event setFirstName:@"JOSE "];
[event …Run Code Online (Sandbox Code Playgroud) core-data objective-c nsmanagedobject nsmanagedobjectcontext ios
我有一个NSOperationQueue,它将对象导入Core Data,这是我从web api获得的.每个操作都有我的应用程序的主要managedObjectContext的私有子managedObjectContext.每个操作都会获取要导入的对象,并检查该对象是否已存在,在哪种情况下它会更新现有对象.如果该对象不存在,则创建此新对象.然后,私有子上下文的这些更改将传播到主要托管对象上下文.
这个设置对我来说非常好用,但是有一个重复的问题.
当我在两个不同的并发操作中导入相同的对象时,我得到具有完全相同数据的重复对象.(它们都检查对象是否存在,并且它们看起来不存在).我将在同一时间导入2个相同对象的原因是我经常处理"新"api调用以及"获取"api调用.由于我的设置同时具有异步性质,因此很难确保我不会尝试导入重复的对象.
所以我的问题是解决这个特定问题的最佳方法是什么?我考虑过限制导入到最大并发操作为1(由于性能,我不喜欢这样).类似地,我考虑在每次导入操作之后要求保存并尝试处理上下文的合并.另外,我之后考虑过修饰数据以偶尔清理重复数据.最后,我考虑过只处理所有获取请求的重复项.但是这些解决方案对我来说都不是很好,也许我已经看过一个简单的解决方案了.
multithreading core-data objective-c nsoperation nsmanagedobjectcontext