公司项目中有一个功能,保存授权令牌数据。最开始只有一条数据,所以就直接保存在了userdefaults中。后来需要两条数据,还是保存在userdefaults中,其中一条为固定的,另一条不固定可以进行替换或删除。最近又需要保存多条数据,那么usedefaults就不适合了,就考虑使用数据库。iOS中可以选择FMDB或CoreData,两者都是基于SQLite数据库的封装,其中CoreData是苹果开发的ORM类型的数据库,在数据量比较少时,两者性能差别不是很大。因为需要在framework中使用,所以尽量不要多引用第三方库,防止和原项目中的库冲突。并且之前项目中用到过在framework中使用CoreData,比较熟悉,所以决定这次也用CoreData。

在framework工程中,新建data model,添加entity和attributes,生成对应的NSManagedObject子类,在CoreDataProperties扩展中添加一些自定义方法,然后打包framework,并将xcdatamodel文件打包到bundle文件中(为mom格式),最后把.framework和.bundle文件拖入原工程中。

编译运行,崩溃并提示

CoreData: warning: Unable to load class named 'AToken' for entity 'AToken'. Class not found, using default NSManagedObject instead.

搜索之后发现这个回答

https://stackoverflow.com/questions/26613971/coredata-warning-unable-to-load-class-named

不过这是使用swift时遇到的问题,但是我用的oc,问题没有解决。

又经过一段时间的搜索,发现有一个问题和我遇到的非常相似

https://stackoverflow.com/questions/27465485/coredata-warning-unable-to-load-class-named-weereadings-for-entity-readings

按照上面的方法在build setting-other linker flags中加入-ObjC,运行,如果可以的话就不用继续往下看了。

但是我的程序运行之后还是崩溃,但是没有崩溃提示,所以我就把-ObjC去掉了。

过了两天,经过各种搜索尝试后,还是没有解决。今天来的时候,我想是不是原有工程中的一些项有影响。然后就新建一个测试项目,把之前生成的framework放进来,但还是提示上面那个错误。我想既然提示没有找到这个类,就在崩溃的地方手动调用initialize方法来加载这个类,这样改过后,错误提示变成这样的

unrecongized selector send to instance

找不到对应的方法,很奇怪怎么会没有呢,百度怎么输出类中的所有方法,结果是这样的

  1. #import <objc/runtime.h>
  2. #import <objc/message.h>
  3.  
  4. -(void)getAllMethods {
  5. unsigned int count;
  6. Method *methods = class_copyMethodList([AToken class], &count);
  7. for (int i = ; i < count; i++) {
  8. Method method = methods[i];
  9. SEL selector = method_getName(method);
  10. NSString *name = NSStringFromSelector(selector);
  11. NSLog(@"方法名字 ==== %@",name);
  12. }
  13. }

在测试项目中调用这个方法,没有输出一个方法,这些方法明明就有,在自动生成的CoreDataProperties扩展中,难道是扩展的问题。我就在网上搜索了这个问题,发现了这个答案

https://blog.csdn.net/qq_28865297/article/details/78227537

按照上面的方法在build setting-other linker flags中加入-ObjC,再次运行,发现可以输出类中所有的方法了,但还是崩溃在向CoreData中插入数据的时候,不过好在这次有错误提示

2019-01-25 13:26:02.833971+0800 FrameworkTest[61131:21155913] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Class 'AToken' for entity 'AToken' has an illegal override of NSManagedObject -isEqual:'

原来是重写isEqual方法导致的,想起之前为了比较自定义类的对象是否相等重写了这个方法,是这样写的

  1. - (BOOL)isEqual:(id)object {
  2. if (self == object) {
  3. return YES;
  4. }
  5. if (![object isKindOfClass:[self class]]) {
  6. return NO;
  7. }
  8. return [self isEqualToToken:object];
  9. }
  10.  
  11. - (BOOL)isEqualToToken:(AToken *)token {
  12. if (!token) {
  13. return NO;
  14. }
  15. BOOL haveEqualToken = (!self.token && !token.token) || [self.token isEqualToData:token.token];
  16. BOOL haveEqualDefault = self.isDefault == token.isDefault;
  17. BOOL haveEqualSaveTime = (!self.saveTime && !token.saveTime) || [self.saveTime isEqualToDate:token.saveTime];
  18. BOOL haveEqualReadCOunt = self.readCount == token.readCount;
  19. return haveEqualToken && haveEqualDefault && haveEqualSaveTime && haveEqualReadCOunt;
  20. }
  21.  
  22. - (NSUInteger)hash {
  23. NSUInteger hash = [super hash];
  24. hash = [self.token hash] ^ self.isDefault ^ self.readCount;
  25. return hash;
  26. }

所以就把isEqual和hash方法注释掉,再重新生成framework,并放到测试项目中,运行,终于没有崩溃了。

困扰了好几天的问题就这样解决了,记录下来,希望可以帮助遇到同样问题的人。

iOS在framework中使用CoreData出现崩溃问题及解决方法的更多相关文章

  1. Robot Framework中ride.py打不开的解决方法

    1.首先查看wxPython版本是否跟python的版本一致,一般都使用wxPython2.8-win64-unicode-2.8.12.1-py27.exe或者wxPython2.8-win32-u ...

  2. ios UITableView中Cell重用机制导致内容重复解决方法

    UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...

  3. ios/iphone手机请求微信用户头像错位BUG及解决方法

    转:http://www.jslover.com/code/527.html ios/iphone手机请求微信用户头像错位BUG及解决方法 发布时间:2014-12-01 16:37:01 评论数:0 ...

  4. WAMP中phpMyAdmin登陆不了问题的解决方法

    WAMP中phpMyAdmin登陆不了问题的解决方法

  5. IOS开发证书变成“此证书的签发者无效”解决方法

    IOS开发证书全部变成无效,如下图  打包提示错误  解决方法: 1. 下载https://developer.apple.com/certificationauthority/AppleWWDRCA ...

  6. 问题-[Access]“无法打开工作组信息文件中的表 'MSysAccounts'”的问题的解决方法

    问题现象:ado.net oledb方式访问Access数据库文件时报错“无法打开工作组信息文件中的表 'MSysAccounts'”的问题的解决方法  问题处理:1.数据库名称不能命名为:Syste ...

  7. PHP开发中常见的安全问题详解和解决方法(如Sql注入、CSRF、Xss、CC等

    页面导航: 首页 → 网络编程 → PHP编程 → php技巧 → 正文内容 PHP安全 PHP开发中常见的安全问题详解和解决方法(如Sql注入.CSRF.Xss.CC等) 作者: 字体:[增加 减小 ...

  8. jquery ui中 accordion的问题及我的解决方法

    原文:jquery ui中 accordion的问题及我的解决方法 jquery有一套所谓的ui组件,很不错的.如果有兴趣的朋友,可以参考http://jqueryui.com/ 但其中的accord ...

  9. ASP.NET MVC中对Model进行分步验证的解决方法

    原文:ASP.NET MVC中对Model进行分步验证的解决方法 在我之前的文章:ASP.NET MVC2.0结合WF4.0实现用户多步注册流程中将一个用户的注册分成了四步,而这四个步骤都是在完善一个 ...

随机推荐

  1. AJAX跨域访问(从Tomcat8到Apache/Nginx/Spring Boot)

    1.在Tomcat的Root目录下放入如下的文件 apache-tomcat-8.0.12X64\webapps\ROOT clientaccesspolicy.xml文件 <?xml vers ...

  2. Spark2.x详解

    一.概述 Apache Spark 是一个快速的, 多用途的集群计算系统. 它提供了 Java, Scala, Python 和 R 的高级 API,以及一个支持通用的执行图计算的优化过的引擎. 它还 ...

  3. Linux 线程调度与优先级

    [转] http://blog.chinaunix.net/uid-20788636-id-1841334.html http://blog.chinaunix.net/uid-20788636-id ...

  4. 前端 css+js实现返回顶部功能

    描述: 本文主要是讲,通过css+js实现网页中的[返回顶部]功能. 实现代码: HTML: <div> <button onclick="returnTop()" ...

  5. Pig autocomplete 自动补全

    在pig的grunt环境下,按TAB键可以自动补全命令,用户可以添加自己的补全信息. 在conf目录下创建autocomplete文件,添加如下内容: hdfs://vm1:8020/   在grun ...

  6. Linq排序方式与Lambda排序方式比较以及OrderBy、ThenBy的使用

    沿用之前某一篇文章的实体类与EF操作类代码.数据库中增加几条数据 Linq 的排序方式,下面例子是根据RoleId 升序,Name降序 EFContext<Member> efMember ...

  7. Invalid argument during startup: unknown conf file parameter : requirepass

    redis 设置来密码,出现来这个错误, 把配置文件那一行的 空格 去掉 # requirepass foobared 改成 requirepass 123456 因为# 和 requirepass ...

  8. [C++] 用Xcode来写C++程序[4] 函数

    用Xcode来写C++程序[4] 函数 此节包括引用函数,内联函数,防止修改函数入参,函数自身带有默认值. 引用函数:防止复制对象,减少系统开销 内联函数:编译的时候根据具体情形将代码嵌入进去,成不成 ...

  9. tomcat7换端口号调试

    1.C:\tomcat\conf\server.xml中修改端口号 2.C:\tomcat\bin\startup.bat批处理文件启动tomcat 3.用ctrl+c结束批处理文件 4.调试结束

  10. 安装zabbix3.4的过程(一)

    目录 zabbix服务端安装(centos7.4) zabbix客户端安装 (centos6.9) 注释:本次安装为官方推荐的yum安装方式,如果需要编译安装,请查看下边的博文: 博文地址:https ...