ios9新特性学习方法和运行时(RunTime)解析

一 ios9的新特性

1 如何学习一个新的API
—–注意: 如何去研究新的API
1.1 百度: iOS9API
1.2 WWDC 和 查看苹果官方文档 (英文基础)
1.3 用最新版本的xcode7创建一个项目,用老版本Xcode6打开
2 掌握几大步骤
​ 2.1 发现:有时候工作无缘无故,会发现新的东西,先保存起来
2.2 研究东西:1.研究作用 2.研究书写格式
2.3 测试:
2.4 注意点:
3 API的历史
—-> 2015 i0S9 Xcode7
—-> 2014 iOS8 Xcode6
—-> 2013 iOS7 Xcode5
—-> 2012 iOS6 Xcode4
4 beta版本:苹果每推出一个新的xcode之前,都会出beta
4.1.让开发人员先熟悉新API
4.2. 不能使用beta版本创建项目
4.3. 不能使用beta版本上传APPStory

二 泛型

1 类型不匹配的警告
2 泛型的用处
2.1 限制类型
3 泛型的好处:
3.1 提示开发者集合中是什么类型,提高代码规范,减少程序猿之间交流
3.2 从集合(数组,字典,NSSet)中取出来的元素可以使用点语法
4 泛型声明格式:在声明类型的时候,声明泛型,在类型后面<泛型名称>
5 泛型定义格式:使用类型才叫定义,类型<限制类型>
6 定义泛型,必须要先声明泛型

三 协变和逆变

1 协变和逆变用于继承类型转换,子类转父类
    __covariant(协变):子类转父类 
    __contravariant(逆变):父类转子类 

四 RunTime

1 OC的底层就是用RunTime去实现的:只有当运行的时候才会知道,会调用哪个方法.
2 RunTime(消息机制):
2.1 方法调用的本质就是发送消息,利用runtime发送消息
2.2 如果需要使用runtime.必须要导入框架: #import
2.3 runtime函数都有前缀,谁的事情谁开头
2.4 千万不要随便使用,不得已才使用
3 消息机制的使用场景:1 装逼 2 调用已知私有方法
4 对象如何找到对应的方法去调用?

注意:每一个类都有方法列表(methodList)

4.1 方法保存到什么地方?对象方法保存到类中,类方法保存到元类(meta class)
4.2 根据对象的isa去对应的类查找方法,isa(指针):判断去哪个类查找对应的方法 指向方法调用的类
4.3 根据传入的方法编号,才能在方法列表中找到对应的方法
4.4 根据方法名(函数入口)找到函数实现
5 用图表示对象是如何找到对应的方法调用(oc底层实现对象找方法)

这里写图片描述

6 (runtime)交换方法
6.1 需求:
需求1:想要在调用imageNamed,就给我提示,是否加载成功
需求2:让UIImage调用imageNamed的时候有这个功能
需求3:比如我有个项目,已经开发2年,之前都是使用UIImage去加载图片,组长想要在调用imageNamed,就给我提示,是否加载成功
6.2 解决思路:
—- 6.2.1 自定义一个UIImage(可以达到目的,但是不满足需求)
—- 6.2.2 给UIImage写一个分类,在分类里写一个加载图片的方法(不满足需求)
—- 6.2.3 用runtime交换方法实现(可以达到目的,也满足需求)
6.3 由于我们需要用到oc底层的方法,所以必须导入头文件
​6.4 给UIImage写一个分类
6.5 在分类中写load方法(交换方法的实现)
代码块一:
#pragma mark - 交换方法
//加载类的时候调用,肯定只会调用一个,不需要担心循环
+ (void)load
{
    Method imageNameMethod = class_getClassMethod(self, @selector(imageNamed:));

    Method XFJ_imageNameMethod = class_getClassMethod(self, @selector(XFJ_imageNamed:));

    method_exchangeImplementations(imageNameMethod, XFJ_imageNameMethod);
}
6.6 给UIImage的分类加一个类方法
代码块二:
#pragma mark - 加载图片的类方法
+ (UIImage *)XFJ_imageNamed:(NSString *)name
{
    UIImage *image = [UIImage XFJ_imageNamed:name];

    if (image == nil) {
        NSLog(@"加载图片失败");
    }
    return image;
}
6.7 在外面调用方法
self.imageView.image = [UIImage imageNamed:@"123"];
6.8 打印出结果,满足条件(用imageNamed方法加载图片,并且有提示是否图片加载成功)

这里写图片描述

7 解析runtime交换方法的原理图:

这里写图片描述

8 原理解析
8.1 image对象找到该方法对应的编号;
​8.2 通过方法的编号,找到方法列表中对应的方法
8.3 通过找到了方法列表中对应的方法,找到对应的方法的实现
8.4 在以上三点方法开始之前,我们通过load方法在OC的底层实现了对两个方法实现的交换
8.5 当外面用对象调用(imageNamed:)的方法的时候其实由于交换的方法实现的原因,该对象会去找(XFJ_imageNamed:)方法的实现,当程序进入了(XFJ_imageNamed:)方法的时候,在运行第二个(XFJ_imageNamed:)方法的时候,其实是调用(imageNamed:)方法,然后再进行判断,如果输入的不是图片,那么自然的显示,加载失败.这就是runtime的交换方法.

五 总结

OC的代码编译的时候都是将OC的代码转为C++来进行编译的,也就是OC的底层都是用C来实现的,那么我们学习了运行时有什么好处呢?学习好了运行时,你能更加的明白到底OC是怎么实现功能的,为什么我们只要一编译链接就能达到某种效果呢,这都是OC的底层封装了C,所以就能达到效果.很多的框架底层也是用运行时来实现的,学习了运行时,我们也就很容易看懂第三方框架了,甚至自己也可以写一些框架,这些都不是什么难事,前提是你必须知道OC的底层是怎么实现的.最后如果大家对我的总结还有什么不足的地方,请多多指教,谢谢!!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值