ios开发runtime学习三:动态添加方法(实际应用少,面试)
#import "ViewController.h"
#import "Person.h" /*
1:
Runtime(动态添加方法):OC都是懒加载机制,只要一个方法实现了,就会马上添加到方法列表中.
app:免费版,收费版
QQ,微博,直播等等应用,都有会员机制
performSelector:去执行某个方法。performSelector withObject :object为前面方法的参数 2:
美团有个面试题?有没有使用过performSelector,什么时候使用?动态添加方法的时候使用过?怎么动态添加方法?用runtime?为什么要动态添加方法?
*/ @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; // _cmd:当前方法的方法编号 Person *p = [[Person alloc] init]; // 执行某个方法
// [p performSelector:@selector(eat)]; [p performSelector:@selector(run:) withObject:@]; } @end
#import "Person.h"
#import <objc/message.h> @implementation Person // 没有返回值,也没有参数
// void,(id,SEL)
void aaa(id self, SEL _cmd, NSNumber *meter) { NSLog(@"跑了%@", meter); } // 任何方法默认都有两个隐式参数,self,_cmd(_cmd代表方法编号,打印结果为当前执行的方法名)
// 什么时候调用:只要一个对象调用了一个未实现的方法就会调用这个方法,进行处理
// 作用:动态添加方法,处理未实现
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
// [NSStringFromSelector(sel) isEqualToString:@"eat"];
if (sel == NSSelectorFromString(@"run:")) {
// eat
// class: 给哪个类添加方法
// SEL: 添加哪个方法
// IMP: 方法实现 => 函数 => 函数入口 => 函数名
// type: 方法类型:void用v来表示,id参数用@来表示,SEL用:来表示
//aaa不会生成方法列表
class_addMethod(self, sel, (IMP)aaa, "v@:@"); return YES;
} return [super resolveInstanceMethod:sel]; } //- (void)test
//{
// // [NSStringFromSelector(sel) isEqualToString:@"eat"];
// if (sel == NSSelectorFromString(@"eat")) {
// // eat
// // class: 给哪个类添加方法
// // SEL: 添加哪个方法
// // IMP: 方法实现 => 函数 => 函数入口 => 函数名
// // type: 方法类型
// class_addMethod(self, sel, (IMP)aaa, "v@:");
//
// return YES;
// }
//
// return [super resolveInstanceMethod:sel];
//}
@end
####3.动态添加方法
* 开发使用场景:如果一个类方法非常多,加载类到内存的时候也比较耗费资源,需要给每个方法生成映射表,可以使用动态给某个类,添加方法解决。
* 经典面试题:有没有使用performSelector,其实主要想问你有没有动态添加过方法。
* 简单使用
```
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Person *p = [[Person alloc] init];
// 默认person,没有实现eat方法,可以通过performSelector调用,但是会报错。
// 动态添加方法就不会报错
[p performSelector:@selector(eat)];
}
@end
@implementation Person
// void(*)()
// 默认方法都有两个隐式参数,
void eat(id self,SEL sel)
{
NSLog(@"%@ %@",self,NSStringFromSelector(sel));
}
// 当一个对象调用未实现的方法,会调用这个方法处理,并且会把对应的方法列表传过来.
// 刚好可以用来判断,未实现的方法是不是我们想要动态添加的方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
if (sel == @selector(eat)) {
// 动态添加eat方法
// 第一个参数:给哪个类添加方法
// 第二个参数:添加方法的方法编号
// 第三个参数:添加方法的函数实现(函数地址)
// 第四个参数:函数的类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd
class_addMethod(self, @selector(eat), eat, "v@:");
}
return [super resolveInstanceMethod:sel];
}
@end
```
ios开发runtime学习三:动态添加方法(实际应用少,面试)的更多相关文章
- ios的runtime为什么可以动态添加方法
一句话概括 每个instance都有一个isa,这个isa,里面含有所有的方法列表,ios提供库函数增加,修改,即实现了动态添加方法
- 使用runtime给类动态添加方法并调用 - class_addMethod
上手开发 iOS 一段时间后,我发现并不能只着眼于完成需求,利用闲暇之余多研究其他的开发技巧,才能在有限时间内提升自己水平.当然,“其他开发技巧”这个命题对于任何一个开发领域都感觉不找边际,而对于我来 ...
- iOS运行时使用(动态添加方法)
1 举例 我们实现一个Person类 然后Person 其实是没得对象方法eat:的 下面调用person的eat方法 程序是会奔溃的 那么需要借助运行时动态的添加方法 Person *p = [[ ...
- ios开发runtime学习四:动态添加属性
#import "ViewController.h" #import "Person.h" #import "NSObject+Property.h& ...
- ios开发runtime学习二:runtime交换方法
#import "ViewController.h" /* Runtime(交换方法):主要想修改系统的方法实现 需求: 比如说有一个项目,已经开发了2年,忽然项目负责人添加一个功 ...
- ios开发runtime学习五:KVC以及KVO,利用runtime实现字典转模型
一:KVC和KVO的学习 #import "StatusItem.h" /* 1:总结:KVC赋值:1:setValuesForKeysWithDictionary实现原理:遍历字 ...
- iOS开发runtime学习:一:runtime简介与runtime的消息机制
一:runtime简介:也是面试必须会回答的部分 二:runtime的消息机制 #import "ViewController.h" #import <objc/messag ...
- ios开发网络学习三:NSURLConnection小文件大文件下载
一:小文件下载 #import "ViewController.h" @interface ViewController ()<NSURLConnectionDataDele ...
- ios开发不能不知的动态修复bug补丁第三方库JSPatch 使用学习:JSPatch导入、和使用、.js文件传输加解密
JSPatch ios开发不能不知的动态修复bug补丁第三方库JSPatch 使用学习:JSPatch导入.和使用..js文件传输加解密 ios开发面临审核周期长,修复bug延迟等让人无奈的问题,所以 ...
随机推荐
- Linux(centos)下mysql编译安装教程
Linux下mysql编译安装教程 #查看linux发行版本 cat /etc/issue #查看linux内核版本号 uname -r 本文測试环境centOS6.6 一.Linux下编译安装MyS ...
- Android基础新手教程——3.8 Gestures(手势)
Android基础新手教程--3.8 Gesture(手势) 标签(空格分隔): Android基础新手教程 本节引言: 周六不歇息,刚剪完了个大平头回来.继续码字~ 好的,本节给大家带来点的是第三章 ...
- eclipse- DDMS截图功能使用
如何使用eclipse的截图功能呢 1.打开eclipse 2.连接手机 3.打开eclipse的DDMS插件. 4.选中手机 5.点击上面的摄像机图标,就可以截图了 如果你打开了DDMS以后,没有发 ...
- 设计模式六大原则(一):单一职责原则(Single Responsibility Principle)
单一职责(SRP)定义: 不要存在多于一个导致类变更的原因,通俗的说,即一个类只负责一项职责. 问题由来: 类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可 ...
- iOS关闭键盘简单实现(objc/swift)
Objective-C 代码实例方式一 [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; 假设一个view上有很多Text ...
- C/C++函数指针声明
前天看APUE,看到signal的声明竟然是 void (*signal(int,void(*)(int)))(int); 初看下面,还真是看不出这是啥意思.道行太浅,仅仅能看到这样的函数指针 voi ...
- ViewPager (下)-- 利用 Fragment 实现美丽的 页面切换
之前用的ViewPager适用于简单的广告切换,但实现页面间的切换最好是用官方推荐的Fragment来处理. 本人力争做到最简单.最有用,是想以后用到的时候能够方便的拿过来复制就能够了. 效果图: w ...
- 转载的:Python os 和 os.path模块详解
os.getcwd()获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell下cd os.curdi ...
- 边缘独立(marginal independent)的理解及举例
1. 定义 ∀xi∈dom(X),yj∈dom(Y),yk∈dom(Y),如果满足, P(X=xi|Y=yj)==P(X=xi|Y=yk)P(X=Xi) 则称随机变量 X 边缘独立于随机变量 Y. 理 ...
- Day1:注释
一.注释方法 1.单行注释用#,本行#号后的内容为注释内容,不执行 2.多行用三个单引号或三个双引号标注,中间内容为注释,不执行 二.其他相关内容 三个引号中的内容还可以当作字符串赋值给变量,可以同时 ...