最近的项目需求需要持久化一些对象,由于只是一些比较简单的数据,使用NSUserDefaults进行存储即可。之前实现过比较简单自动archive和unarchive的操作。原理很简单,遍历NSObject的property list,然后通过valueForKey:和setValue:forKey:方法进行操作。这种实现不能满足我的新需求,我的新需求需要做到将property为其他类型的对象也做到自动archive和unarchive,再加上JSON解析方面的工作量,直接粗暴通过硬编码实现会产生一大堆verbose的代码,自己实现需要自动化archive和unarchive的代码需要的工作量较大。于是顺便看了一下Mantle的源代码,发现其中这方面的处理很不错,各方面很合理,就通过这个实现了。
Mantle解析JSON或者NSCoding操作我认为实际上都可以分成两个大步骤来阅读:
Transform 和
赋值 。Mantle的源代码不是很多,但是代码很干净,注释也很完善。
我把全部文件根据我认为的步骤进行了一下分类:
1. Transform相关:
MTLJSONAdapter
MTLManagedObjectAdapter
MTLValueTransformer
NSValueTransformer+MTLInversionAdditions
NSValueTransformer+MTLPredefinedTransformerAdditions
MTLModel+NSCoding
2.赋值相关:
MTLModel
3.工具类:
MTLReflection:
NSArray+MTLManipulationAdditions
NSDictionary+MTLManipulationAdditions
NSError+MTLModelException
NSObject+MTLComparisonAdditions
4. extobjc:
MTLEXTKeyPathCoding
MTLEXTRuntimeExtension
MTLEXTScope
metamacros
从NSDictionary到Model
把JSON数据解析为Model只需要下面两行代码即可:
Transform过程
从JSON转换到model,方法入口是在 MTLJSONAdapter 的 modelOfClass:fromJSONDictionary:error: ,详细逻辑的实现方法是 - (id)initWithJSONDictionary:modelClass:error: 。这个方法在入口处进行了assert,modelClass的类型必须是MTLModel的子类,同时modelClass必须实现MTLJSONSerializing protocol。
接下来就是上面这段代码,这段代码比较有意思,它涉及到一个我们经常使用却不太在意的东西,类簇(class cluster),这个设计模式在Cocoa中使用很广泛,最明显的例子是NSNumber,关于class cl