object-c编程tips-jastor自动解析

前言

过去写iphone程序一直都没有用过自动解析,都是手动按着字典一层一层的解析,这样费时费力,还容易出错。后来公司来了新朋友带来了自动解析的jastor库,着实不错。

简单介绍一下jastor

jastor是一个基于oc运行时的库,它可以将字典对象转换成NSObject对象。它支持NSString, NSNumber,NSArray, NSDictionary以及它们的嵌套类型。例如现在需要将dict转换为model。 dict为NSDictionary对象, model为继承于Jastor的NSObject对象。 Jastor通过遍历model对象的所有属性, 以属性作的名字作为dict的key,得到字典的value值。 然后根据value值的类型,进行不同的处理。 如果value是NSArray类型,那么就进入NSArray的解析流程;
如果value是NSDictionary类型,那么开始进行递归调用,如果是其他普通类型,则直接setvalue:forKey。当进入NSArray的处理流程时候,调用类的“属性_class”方法获取到数组对象的类型,然后对数组对象进行逐步解析,数组对象也必须是字典类型。

为什么写这篇博客?

Jastor确实可以大大简化代码的解析流程,当然效率肯定没有手动解析的效率高,这个可以从代码的递归流程以及使用Runtime的各种遍历方法中可以看出。 但是作为开发人员,这么点的效率损失可以带来大量代码的简洁,减少开发人员的出错几率,它的益处是显而易见的。当第一次使用Jastor时候,着实为它的代码的简洁所吸引,主要的有递归解析思想,rumtime的相关内容, 组合模式,缓存机制。后来加入到代码中后,总会有一些崩溃的情况,主要是一些容错性的问题,毕竟我们没有办法要求服务器下发的json数据每次都是和我们要求的一直,总有一些不一致的情况引起意想不到的问题。

Jastor递归解析

Jastor本身是一个基类,它可以将字典转换成model, 如果字典的某一个成员又是字典,那么它可以递归进去继续解析,直到遇到的是一个普通的单一数据类型例如NSString,NSNumber等等为止,通过这样层层的递归,深入到最里层后也就是Jastor解析的结束。它通过for循环遍历当前类的所有属性,逐一寻找属性在字典里面的value值,根据value值的不同类型以及属性的类型决定下一步进行递归解析还是直接setValueForKey。

            if ([dictOrArray isKindOfClass:nsDictionaryClass]) {
                value = [dictOrArray valueForKey:jsonKey];

                if (value == [NSNull null] || value == nil) {
                    continue;
                }

                if ([JastorRuntimeHelper isPropertyReadOnly:[self class] propertyName:classAttrName]) {
                    continue;
                }

                // handle dictionary
                if ([value isKindOfClass:nsDictionaryClass]) {
                    Class klass = [JastorRuntimeHelper propertyClassForPropertyName:classAttrName ofClass:[self class]];
                    if (![klass isSubclassOfClass:[Jastor class]]) {
                        NSLog(@"服务器返回的数据类型和客户端不一致");
                        continue;
                    }
                    value = [[[klass alloc] initWithDictOrArray:value] autorelease];
                }
                // handle array
                else if ([value isKindOfClass:nsArrayClass]) {
                    value = [self dealWithArrayValue:value attrName:classAttrName jsonKey:jsonKey];
                }
                // handle nsnumber
                else if([value isKindOfClass:[NSNumber class]]){
                    value = [(NSNumber *)value stringValue];
                }

            }

请看上面的代码,当传入的是dict的时候,会进入到此if流程中, 首先判断value是否为空,如果为空,直接跳过;然后判断属性是只读,只读也直接跳过;然后判断value是字典的情况,如果是字典进行递归深入;然后判断是数组的情况,数组进行数组元素的遍历解析,最后判断是NSNumber,得到NSNumber的string值。 得到最后的value后,会进行如下的操作

            // handle all others
            if (value) {
                [self setValue:value forKey:classAttrName];
            }

Jastor的Runtime

Runtime用的比较好, 其实里面也就几个方法而已,不过由于用的比较少,可能感觉它有些高大上了,其实仔细看看,也是普通的属性遍历而已。总共就几个方法: 判断属性是否可读,获取一个类对象的所有属性列表数组,判断指定类对象的给定属性的类型。所有的方法基于一个基本的思想: 遍历类对象的所有objc_property_t的属性进行处理。 这里面效率肯定比较低,但是这里面作者用了缓存的思想,无缓冲就遍历并写入缓存,下次直接读缓存。

Jastor的组合模式

派生类的model继承于Jastor,派生类model的某一个属性可能也继承于Jastor。一个大的model是一堆Jastor的子类的组合, 通过这种类似于组合模式的思想,贯穿到递归数据解析中,只是通常的组合模式不是类和属性的组合,而且集合和单品元素的组合,其实原理的精髓是一样的。

Jastor的缓存机制

可以看到里面有各种缓存,包括获取属性列表,是否可读,获取指定属性的类对象,获取常用类的类对象等等,都进行的缓存操作,只用了几个简简单单的字典,却可以大大提高程序的执行效率,相当不错。

Jastor的容错性

Jastor本身已经进行了各种容错,不过对于应用来说还是有些缺陷的,毕竟程序可以出错,但不可以崩溃,这是一个基本准则。因此,我主要通过猜,试验,发现了几个崩溃点,和同事一起进行了修正,加入了几个容错,至少在我们的应用中,并没有出现崩溃的情况。

Jastor的map特性

新版的Jastor加入了map,属性名称可以任意,赋予程序以最大的灵活性。原来我们使用的这一版没有这种内容,我们组的牛人波波同志加入了map机制,刚开始我感觉必要性不是很大,但是随着后期的项目的推进,确实用处极大。

对于Jastor,代码我就不贴了,Github有库,GitHub地址。 对于Jastor出现崩溃的情况,一定要跟进Jastor里面,找到问题,加入保护即可。

object-c编程tips-jastor自动解析

时间: 2024-10-20 04:50:00

object-c编程tips-jastor自动解析的相关文章

Java编程Tips

原文: Java编程中"为了性能"尽量要做到的一些地方 作者: javatgo 最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: 控制资源的使

6、Java并发编程:volatile关键字解析

Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatil

iphone 浏览器自动解析数字为号码解决方法

iphone 浏览器自动解析数字为号码解决方法 www.MyException.Cn  网友分享于:2015-10-09  浏览:0次 iphone 浏览器自动解析数字为号码解决办法 在工作中遇到了这么一个问题 —— 在HTML代码中有一部分数字,设定的样式为“白色”,在android 浏览器 和 PC web中显示都是正常的,但是在iphone浏览器中先显示为白色,之后有变为“黑色”,在点击这串数字的时候,显示为拨打电话界面. 分析: 根据上图展现的方式说明“1234-5678-9999”添加

[Object]面向对象编程(自己总结版)

[Object]面向对象编程(自己总结版) 2014-06-06 面向对象编程 感受:原理javascript也可以用完全面向对象的方式编程,兴奋得一个晚上都没睡好觉. 有种越深入越想编程的状态,有种上瘾的快感. 1,面向对象方式编程 Js代码   function Aa(){ //属性设置 this.property1:value1,//例如this.nameinput = $("input['name'=name]"); this.property2:value2, this.pr

[Object]面向对象编程(高程版)(0)属性和方法

[Object]面向对象编程(高程版)(0)属性和方法 博客分类: Web前端-JS语言核心 私有变量成员变量公有变量静态变量 zccst转载+原创 Js代码   function Person(){ var private_name = "小明"; //私有属性 var private_age = 10;      //私有属性 this.privilege_name = "小红"; //特权属性 this.privilege_age = 9;       //特

编程Tips

三元运算符 Vb中的iif(expr,truepart,falsepart)和C#中的expr?truepart:falsepart. 无论expr的结果是true还是false,true/falsepart都会被执行.所以不能写类似于obj!=null?obj.name:string.empty. truepart和falsepart的语句返回类型必须相同. 反射会造成性能损失,所以在多次调用某个语句,而该语句又使用反射获取信息时,应该进行代码改造. VB中的AndAlso类似于C#中的&&am

WebApi系列~FromUri参数自动解析成实体的要求

回到目录 关于webapi我之前写了一些文章,大家可以根据目录去浏览,今天要说的是个怪问题,也是被我忽略的一个问题,当你的Url参数需要被Api自动解析成实体的属性,实事上是要有条件的,不是所以属性都可以被自动赋值的,下面我们就来看看先决条件: 条件一:类属性名称必须和参数名称相同 条件二:API参数必须以[FromUri]来修饰 条件三:属性类型为“类”的,如果使用类名(导航属性在本类的名称,可以不是类的原名).属性名的形式,例如Page.PageIndex 条件四:属性类型为“数组,集合”时

object-c编程tips

如何写一个对扩展开发对修改关闭的推送消息处理中心? 前一段时间做的推送消息处理,总是要根据不同的消息类型,进入到不同的消息处理流程中.由于消息处理流程的总体框架大同小异,只是具体的很小的一块代码不同. 于是很容易想到使用模板方法模式基类写框架流程,派生类负责具体的实现. 需要有三个类: LPPushDispatchCenter: 消息处理中心类 LPPushDispatch :消息处理基类 LPDetailPushDispatch(很多很多个这样的派生类): 消息处理派生类 所有的消息首先进入消

Java并发编程:volatile关键字解析 和双重检查(Double-Check)

转载:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的