iOS·NSObject的两种含义:类与协议

iOS·NSObject的两种含义:类与协议,第1张

iOS开发中,苹果提供的一些系统类都属于NSObject的子类,例如UIColor类的定义如下所示。

或者自定义的类,也继承自NSObject,例如下图所示。

但是,NSObject不仅仅代表基类,还有协议的意思,我们可以称之根协议,例如下图所示:

事实上,从NSObject类的定义可知,NSObject的类本身就遵循NSObject协议,如下图所示。

假设你自定义一个继承自UITextField的子类MyTextFeild,同时自定义一个代理MyTextFeildDelegate的属性如下:

这时候会报错的,因为这个 子类中delegate属性的协议类型,与父类的delegate属性的协议类型冲突 。一个解决办法是 利用协议的多继承:让子类中自定义的协议继承自系统父类中的系统协议

OC里面的类本来是不支持多继承的,但有的面试官还是会问到iOS里面如何实现多继承?除了运行时的办法,还有一种就是通过协议的多继承来实现。当然,分类亦可以讲讲。

在开发的过程中,对一个NSMutableDictionary(可变字典)设置键值对的时候,一般会采用setObject这个方法,但是在项目中,去云捕上看到的用户出错,好多都是报这样的错误。

很明显就是在setObject方法中插入了空值而导致的报错。解决的办法是将setObject替换成setValue就可以了。虽然解决了,但是他们之间的区别以及为什么setValue就可以呢?

因为setObject方法中,值必须是不为空的任意类型(nonnull),而setValue方法中,值可以为空值(nullable),并且在setValue方法中,假如你传的值为空的话,那么他会调用- (void)removeObjectForKey:(id)aKey这个方法。所以用setValue方法可以有效的防止值为空所出现的炸裂现象。

注意:在系统给出的方法中,我们可以明显的看到,setValue方法中,key必须是不为空的字符串(nonnull NSString),而setObject方法中,可以传入不为空的id类型。

setValue和setObject的一些拓展�:

1.setObject方法是NSDictionary这个类中特有的,而setValue是KVC(key-value-coding  键值编码)中的主要方法。

2.setObject方法中,虽然值不能为nil,但是可以为[NSNull null],并且key可以为NSString, NSNumber等类型。

3.当 setValue:forKey:方法调用者是对象的时候:

setValue:forKey:方法是在NSObject对象中创建的,也就是说所有的oc对象都有这个方法,所以可以用于任何类。

比如使用一个person类:

Person *person = [[Person alloc] init]

[person setValue:self forKey:@"delegate"]

表示的意思是:对象person设置他的delegate属性的值为当前类,当然调用此方法的对象必须要有delegate属性才能设置,不然调用了也没效果。(这条目前还不太理解,希望有看到的大神指教)

setValue和setObject参考链接:http://blog.csdn.net/itianyi/article/details/8661997

​ iOS源码解析—YYModel(YYClassInfo) 分析了如何根据OC的Class对象构建YYClassInfo对象,为接下来的JSON数据和Model转换作准备,这篇文章开始讲解NSObject+YYModel。

​ 分析NSObject+YYModel.h文件,包括3个Category和一个protocol,分别是:

字典studentDic中的key对应原字典playerDic中的key,studentDic中的Model由playerDic中的value转化得到。

首先定义了两个类,_YYModelMeta和_YYModelPropertyMeta,分别封装了Model的信息和Model中各属性的信息。

_YYModelMeta维护了Class的相关信息,下面是注释:

_YYModelMeta是通过YYClassInfo对象的信息构建得到的。首先调用metaWithClass:cls方法,该方法如下:

维护了一个键值对cache作为缓存,用cls作为key,调用CFDictionaryGetValue方法去缓存中查找,如果有,直接返回构建好的_____YYModelMeta对象,如果没有找到或者needUpdate属性标记为true,则根据cls创建一个新的_YYModelMeta对象,并且存入缓存。这样不需要每次都创建,提高了性能。

接下来看一下initWithClass:方法,

下面分析几个重要的方法:

YYModel的总体思想是以Model属性的类型为准,如果JSON中对应名称的value的类型和Model属性类型不一致,会对value的类型进行转化,保证和Model属性的类型一致。如果兼容不了,不进行属性赋值。下面分析一下ModelSetValueForProperty方法:

该方法上文中提到该方法是用来JSON转成Model的过程中对Model中的属性进行赋值的方法,该方法做了部分基本类型的兼容:

YYModel还提供了一些工具方法,下面简单分析一下:

YYModel作为一个负责JSON数据和Model转化的库,十分易用和高效,特别是做了一些类型的兼容和转化,避免了服务端接口数据类型和客户端Model对象类型不兼容导致的问题,例如执行了不存在的方法而导致崩溃。另一方面,对YYModel的学习在一定程度也促进了对runtime机制的学习和了解。

关于YYModel的分析到这儿先告一段落,由于本人的iOS基础有待提升,再加上表达能力有限,文中许多地方的分析和思路,表达的不是很准确和清楚,希望通过今后的学习和练习,提升自己的水平。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/7981760.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-12
下一篇 2023-04-12

发表评论

登录后才能评论

评论列表(0条)

保存