CoreData Crash

来源:互联网 发布:ubuntu 16.04 安装后 编辑:程序博客网 时间:2024/06/05 22:30

1. 使用Core Data时Model Class的定义:

  • property必须是Objective C的对象类型,必须声明为nonatomic & retain或 nonatomic ?
  • 在.m文件中accessor方法用@dynamic, refenrence里面是strongly recommend这样用的
  • 如果property是数字,用NSNumber *,调用的时候再换成需要的类型。
    • 例如 cell.text = [NSNumber stringValue: (NSNumber *)];

2. 修改.xcdatamodel文件引起的Exception:'Can't merge models with two different entities named '……'

  • 如果在程序已经运行过的情况下更改了.xcdatamodel文件,原有数据库就作废了,所以无论怎么调试都会出现exception。一般console里面会提示NSPersistentStoreCoordinator has no persistent stores.
  • 解决方法:找到.sqlite,然后删掉,重新运行。.sqlite文件在Library/Application
    Support/iPhone Simulator/User/Applications/(一堆数字,点进去会看见project名)/Documents/;若以上方法还不能解决,就将Applications目录下的所有文件夹删除,得以解决(2013年2月16日,发现该问题,非转载,本人自创);
  • 详细参考:http://objitsu.com/blog/2009/10/01/nspersistentstorecoordinator-has-no-persistent-stores/

3. 所有跟text有关的UI类的setText方法只能用NSString,否则会有warning,如果不管这个warning运行时会exception.

4. 如何调试EXE_BAD_ACCESS

  • 详细参考:http://www.codza.com/how-to-debug-exc_bad_access-on-iphone

5. unrecognized selector sent to instance xxxx

  • 造成unrecognized selector sent to instance iphone,大部分情况下是因为对象被提前release了,在你心里不希望他release的情况下,指针还在,对象已经不在了。很多时候,是因为init初始化函数中,对属性赋值没有使用self.foo赋值,而是直接对foo赋值,导致属性对象没有retain(心里以为retain了),而提前释放。有时候也能是初始化函数用错了。
  • 解决方法:检查release和init

6. Can’t merge models with two different entities named xxxx

  • 修改了Core Data的数据模型后,因为版本问题出现的Exception
  • 解决办法:Build —>clear all target
  • 参考资料:Core Data Migration and Version
    • http://www.timisted.net/blog/archive/core-data-migration/

7. could not locate an NSManagedObjectModel for entity name

  • managedObjectContext没有初始化,所以无法读取model的值
  • 调试方法:将appDelegate的context传给viewController前,要将viewController的context初始化,囧囧是写在initWithNibName里的 

8.UITableView的数据源排序为降序时,记得CellForRowAtIndexPath里面不要用if(Cell ==nil)的条件去掉,否则数据更新会错。。。

9.  使用Core Data时,实体类的relationship在fetch的时候只作为fault被调用

fault是为了保证模型完整的一种东西,比如说A有个relationship ,这个关系的目标是B,那fetch A的时候,B只是个fault,你是无法访问B的属性的,因为B根本没被fetch ,下面是囧囧的解决方法,也不知道对不对,哈哈哈哈- - 

 [fetchRequest setReturnsObjectsAsFaults:NO]; 


10.coreData部分报错:This NSPersistentStoreCoordinator has no persistent stores.

遇到一个很奇怪的现象。unit测试时,coreData部分报错:This NSPersistentStoreCoordinator has no persistent stores.

但实际跑程序时。增删保存都没问题。

我花了很多的时间在问题抛出的地方在[contextsave:&error]; 

后来发现,早在初期化_persistentStoreCoordinator 时就报错了

    if (![_persistentStoreCoordinator

         addPersistentStoreWithType:NSSQLiteStoreType

         configuration:nil

          URL:storeUrl

          options:nil

          error:&error]) {

       // Handle the error.

    } 


&error 显示的信息为The model used to open the store is incompatible with the one used to create

上网搜了下,大意是说可能在改变entities的atrributes时损坏了存储文件。直接把存储文件删除即可。

我试了下,果然就ok了。

另外两个人和我的现象是一样的,不过在storeUrl指定的地方根本没有文件夹,别说文件了。按照storeUrl

的路径把文件夹建好,也就ok了。

我还有个疑问,为什么实际跑画面的时候是好的。只有单体测试的时候有问题?

我又在跑画面的时候,跟进去看了下。实际跑画面的storeUrl的根路径与单体时不同,有一串看似是UUID的随机数。

估计是跑画面的时候有建新目录的权限。

而跑单体的时候既没有建目录权限,也没有删文件权限。所以当存储改变时会报错。

11.CoreData修改以后防止Cash的方法

转载
说是防止Cash,但其实是让Core Data 自己把数据转换映射到新的数据库中去的感觉。只要对 persistentStoreCoordinator 做修改就好了。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {


    if (persistentStoreCoordinator != nil) {

        return persistentStoreCoordinator;

    }


    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"database.sqlite"]];


    NSError *error = nil;

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

                                               [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {

        // Handle error

    }    


    return persistentStoreCoordinator;

}



0 0