Bro*_*bie 31 iphone exception core-data
我正在做一个从XML文件中读取数据的iPhone应用程序,将它们转换为Core Data Managed Objects并保存它们.
应用程序工作正常,主要是在包含~150个对象的较小数据集/ XML上.我说的主要是因为10%的时间,我在尝试保存上下文时会从CoreData获得以下异常:
*由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'* -_referenceData64仅为抽象类定义.定义 - [NSTemporaryObjectID_default _referenceData64]!'
在更大的数据集(~2000)上,每次都会发生这种情况,但不是在同一个地方.它可能在第137个记录,第580个或最后一个记录中失败.我已经尝试移动保存点(每个对象,每10个对象,保存一旦所有对象都是alloc/init')但我总是点击上面的异常.
我用谷歌搜索了例外,看到有人遇到同样的问题,但没有看到任何解决方案.
我的下一步是将托管对象和关系简化为此错误停止并从那里构建以隔离问题的点.最后一招是放弃Core Data,直接存入sqllite.
感谢你的帮助!
Adr*_*ing 30
我有同样的问题.它适用于较小的数据集,但对于较大的集合,我得到"_referenceData64仅为抽象类定义"错误.我的模型中没有抽象实体.
编辑:
我想我已经解决了这个问题.在我的案例中的问题是我的线程混乱.以下是我修复它的指导原则:
NSManagedObjectID *objectID = [foo objectID];
FooClass *newFoo = [(FooClass*)[threadManagedObjectContext objectWithID:objectID] retain]`
 - (void)onFinishParsing {  
  // lock the store we share with main thread's context  
  [persistentStoreCoordinator lock];  
  // save any changes, observe it so we can trigger merge with the actual context  
  @try {  
    [threadManagedObjectContext processPendingChanges];  
  }  
  @catch (NSException * e) {  
    DLog(@"%@", [e description]);  
    [persistentStoreCoordinator unlock];  
  }  
  @finally {  
    // pass  
  }  
  NSNotificationCenter *dnc = [NSNotificationCenter defaultCenter];  
  [dnc addObserver:self selector:@selector(threadControllerContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:threadManagedObjectContext];  
  @try {  
    NSError *error;  
    if (![threadManagedObjectContext save:&error]) {  
      DLog(@"%@", [error localizedDescription]);  
      [persistentStoreCoordinator unlock];  
      [self performSelectorOnMainThread:@selector(handleSaveError:) withObject:nil waitUntilDone:NO];  
    }  
  } @catch (NSException *e) {  
    DLog(@"%@", [e description]);  
    [persistentStoreCoordinator unlock];  
  } @finally {  
    // pass  
  }  
  [dnc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:threadManagedObjectContext];  
  [self performSelectorOnMainThread:@selector(parserFinished:) withObject:nil waitUntilDone:NO];  
}  
// Merging changes causes the fetched results controller to update its results  
- (void)threadControllerContextDidSave:(NSNotification*)saveNotification {  
  // need to unlock before we let main thread merge  
  [persistentStoreCoordinator unlock];  
  [self performSelectorOnMainThread:@selector(mergeToMainContext:) withObject:saveNotification waitUntilDone:YES];  
}  
- (void)mergeToMainContext:(NSNotification*)saveNotification {  
  NSError *error;  
  [managedObjectContext mergeChangesFromContextDidSaveNotification:saveNotification];  
  if (![managedObjectContext save:&error]) {  
    DLog(@"%@", [error localizedDescription]);  
    [self handleSaveError:nil];  
  }  
}  
`
Ans*_*ari 13
你必须遵守规则:
必须在使用它的同一线程上创建NSManagedObjectContext.(或者换句话说,每个线程必须有自己的MOC)
违反上述规则会导致以下异常:
- ***-_referenceData64中的异常仅为抽象类定义.定义 - [NSTemporaryObjectID_default _referenceData64]!,
有人可能面临的另一个问题是,如果使用NSFetchedResultsController,则不会在UI类上调用委托.
我希望这个答案会对某人有所帮助!
小智 7
简短回答: \n保存上下文时必须使用以下函数,以确保在为上下文指定的队列上执行块操作。
\n\nperform(_:)\nperformAndWait(_:) \n正如 Apple 文档中 NSManagedObject 并发部分中提到的\n此处
\n\n长答案: \n如 Apple 文档中所述
\n\n\n\n\nCore Data 使用线程(或序列化队列)限制来保护托管对象和托管对象上下文(请参阅 Core Data 编程指南)。这样做的结果是上下文假定默认所有者是分配它的线程或队列\xe2\x80\x94,这是由调用其 init 方法的线程确定的。因此,您不应该在一个线程上初始化上下文,然后将其传递给另一个线程。相反,您应该传递对持久存储协调器的引用,并让接收线程/队列创建一个新的派生上下文来自\n那。
\n
由此我们可以假设
\n\n这会在你的脑海中产生一个新的问题
\n\n\n\n\n有没有办法找出 NSManagedObjectContext 所在的线程\n?
\n
这里已经回答了,汤姆·哈林顿的回答将证明上面的每件事都有点不准确(我也相信)并将我们重定向回简短的答案:)
\n| 归档时间: | 
 | 
| 查看次数: | 13818 次 | 
| 最近记录: |