公司項目中有一個功能,保存受權令牌數據。最開始只有一條數據,因此就直接保存在了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文件拖入原工程中。swift
編譯運行,崩潰並提示app
CoreData: warning: Unable to load class named 'AToken' for entity 'AToken'. Class not found, using default NSManagedObject instead.ide
搜索以後發現這個回答性能
https://stackoverflow.com/questions/26613971/coredata-warning-unable-to-load-class-named測試
不過這是使用swift時遇到的問題,可是我用的oc,問題沒有解決。ui
又通過一段時間的搜索,發現有一個問題和我遇到的很是類似spa
按照上面的方法在build setting-other linker flags中加入-ObjC,運行,若是能夠的話就不用繼續往下看了。code
可是個人程序運行以後仍是崩潰,可是沒有崩潰提示,因此我就把-ObjC去掉了。
過了兩天,通過各類搜索嘗試後,仍是沒有解決。今天來的時候,我想是否是原有工程中的一些項有影響。而後就新建一個測試項目,把以前生成的framework放進來,但仍是提示上面那個錯誤。我想既然提示沒有找到這個類,就在崩潰的地方手動調用initialize方法來加載這個類,這樣改事後,錯誤提示變成這樣的
unrecongized selector send to instance
找不到對應的方法,很奇怪怎麼會沒有呢,百度怎麼輸出類中的全部方法,結果是這樣的
#import <objc/runtime.h> #import <objc/message.h> -(void)getAllMethods { unsigned int count; Method *methods = class_copyMethodList([AToken class], &count); for (int i = 0; i < count; i++) { Method method = methods[i]; SEL selector = method_getName(method); NSString *name = NSStringFromSelector(selector); NSLog(@"方法名字 ==== %@",name); } }
在測試項目中調用這個方法,沒有輸出一個方法,這些方法明明就有,在自動生成的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方法致使的,想起以前爲了比較自定義類的對象是否相等重寫了這個方法,是這樣寫的
- (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[self class]]) { return NO; } return [self isEqualToToken:object]; } - (BOOL)isEqualToToken:(AToken *)token { if (!token) { return NO; } BOOL haveEqualToken = (!self.token && !token.token) || [self.token isEqualToData:token.token]; BOOL haveEqualDefault = self.isDefault == token.isDefault; BOOL haveEqualSaveTime = (!self.saveTime && !token.saveTime) || [self.saveTime isEqualToDate:token.saveTime]; BOOL haveEqualReadCOunt = self.readCount == token.readCount; return haveEqualToken && haveEqualDefault && haveEqualSaveTime && haveEqualReadCOunt; } - (NSUInteger)hash { NSUInteger hash = [super hash]; hash = [self.token hash] ^ self.isDefault ^ self.readCount; return hash; }
因此就把isEqual和hash方法註釋掉,再從新生成framework,並放到測試項目中,運行,終於沒有崩潰了。
困擾了好幾天的問題就這樣解決了,記錄下來,但願能夠幫助遇到一樣問題的人。