Objective-C runtime初识
Objective-C Runtime
Note
char *
in the runtime API should be considered to have UTF-8 encoding.struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
id objc_msgSend(id self, SEL _cmd, …);
/**
要动态绑定的方法 @param self 要绑定方法的对象
@param _cmd 方法信息
*/
void dynamicMethodIMP(id self, SEL _cmd) { NSLog(@"SEL: %s method is added", sel_getName(_cmd));
NSLog(@"Name: Jackey");
} /**
动态绑定和解析方法 @param sel 方法信息
@return 是否已经处理该方法
*/
+ (BOOL)resolveInstanceMethod:(SEL)sel { NSLog(@"SEL: %s method does not exist", sel_getName(sel)); if (sel == @selector(printName)) { class_addMethod ([self class], sel, (IMP) dynamicMethodIMP, "v@:");
return YES;
} return [super resolveInstanceMethod:sel];
}
这样我们再运行[[ClassA new] printName];就会输出Name: Jackey
重定向:
如果经过动态解析后, 消息还没有被响应就会进入到重定向阶段
我们可以重写- (id)forwardingTargetForSelector:(SEL)aSelector将消息重定向给可以响应的对象
/**
方法重定向 @param aSelector 方法信息
@return 返回重定向后要相应的对象
*/
- (id)forwardingTargetForSelector:(SEL)aSelector { NSLog(@"Current class can't response to SEL: %s", sel_getName(aSelector)); if (aSelector == @selector(printRightName)) { NSLog(@"Forward to target: %@", [ClassB class]);
return [ClassB new];
} return [super forwardingTargetForSelector:aSelector]; }
最后如果前面都没有处理就会进入到消息转发, 我们可以通过重写
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector;
- (void)forwardInvocation:(NSInvocation *)anInvocation;
来自定义
/**
转发前, 获取方法签名 @param selector 方法信息
@return NSInvocation消息对象
*/
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { NSString *sel = NSStringFromSelector(selector);
if ([sel rangeOfString:@"set"].location == ){ return [NSMethodSignature signatureWithObjCTypes:"v@:@"];
}
else{ return [NSMethodSignature signatureWithObjCTypes:"@@:"];
}
} /**
转发 @param anInvocation 消息对象
*/
- (void)forwardInvocation:(NSInvocation *)anInvocation { NSLog(@"No class can't response to SEL: %s", sel_getName([anInvocation selector])); ClassC *c = [ClassC new];
if ([c respondsToSelector:[anInvocation selector]]) { NSLog(@"method apply deliver to %@", [ClassC class]);
[anInvocation invokeWithTarget:c];
} else { [super forwardInvocation:anInvocation];
}
}
消息的转发弥补了OC不能多继承的问题
最后我们来看下Method Swizzling
我们可以直接修改方法的指针, 让一个方法名指向其他的方法实现
Method ori_method = class_getInstanceMethod([ClassB class], @selector(printRightName));
Method my_method = class_getInstanceMethod([ClassC class], @selector(printFamilyName)); method_exchangeImplementations(ori_method, my_method); [[ClassB new] printRightName];
使用method_exchangeImplementation交换了两个对象方法的指针
printRightName执行的实际是printFamilyName
Objective-C runtime初识的更多相关文章
- Objective C Runtime 开发介绍
简介 Objective c 语言尽可能的把决定从编译推迟到链接到运行时.只要可能,它就会动态的处理事情.这就意味着它不仅仅需要一个编译器,也需要一个运行时系统来执行变异好的代码.运行时系统就好像是O ...
- Runtime初识
什么是Runtime 我们写的代码在程序运行过程中都会被转化成runtime的C代码执行,例如[target doSomething];会被转化成objc_msgSend(target, @sel ...
- 刨根问底Objective-C Runtime(4)- 成员变量与属性
http://chun.tips/blog/2014/11/08/bao-gen-wen-di-objective[nil]c-runtime(4)[nil]-cheng-yuan-bian-lian ...
- Runtime-b
感谢大神分享 依旧是网上很多runtime的资料,依旧是看不懂,,,这里给大家转化一下runtime,使它由隐晦难懂变得通俗易懂. (虽然截图和语言组织的有些凌乱,但是大家还是一点一点的阅读下去吧,可 ...
- Objective-C Runtime(一)预备知识
很早就知道了Objective-C Runtime这个概念,「Objective-C奇技淫巧」「iOS黑魔法」各种看起来很屌的主题中总会有它的身影:但一直没有深入去学习,一来觉得目前在实际项目中还没有 ...
- iOS-运行时机制
这里的两篇运行时的文章感觉还不错. 收藏: 初识iOS运行时RunTime | // TODO: http://www.saitjr.com/ios/objc-runtime.html Objecti ...
- 据说是百度ios面试题
百度面试题: 一面:知识点 Objective C runtime library: Objective C的对象模型,Block的底层实现结构,消息发送,消息转发,内存管理 CoreData : ...
- iOS 面试基础题目
转载: iOS 面试基础题目 题目来自博客:面试百度的记录,有些问题我能回答一下,不能回答的或有更好的回答我放个相关链接供参考. 1面 Objective C runtime library:Obje ...
- objc_msgSend消息传递学习笔记 – 消息转发
该文是 objc_msgSend消息传递学习笔记 – 对象方法消息传递流程 的基础上继续探究源码,请先阅读上文. 消息转发机制(message forwarding) Objective-C 在调用对 ...
随机推荐
- C# 文章导航
1. C#相关文章 1.1 C# 基础(一) 访问修饰符.ref与out.标志枚举等等 1.2 C# 基础(二) 类与接口 1.3 C# DateTime日期格式化 1.4 C# DateTime与时 ...
- 【小计】新人Tostring前忘记Null判断的处理
ToString和string.Concat(可屏蔽Null的异常)性能相差不大,一些中小项目完全可以用Concat(新人容易忘记判断Null的情况,遇到太多了,所以建议重写tostring方法,内部 ...
- Ubuntu 16.10 安装KolourPaint 4画图工具
KolourPaint 4画图工具简单实用,可以绘画.视频处理和图标编辑: • 绘画:绘制图表和“手绘” • 视频处理:编辑截图和照片;应用特效 • 图标编辑:绘画剪贴和标识透明化 1.在Ubuntu ...
- pdo的使用
PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口. PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据. PDO随 ...
- RIFF和WAVE音频文件格式
RIFF file format RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构.RIFF文 ...
- [原] KVM 环境下MySQL性能对比
KVM 环境下MySQL性能对比 标签(空格分隔): Cloud2.0 [TOC] 测试目的 对比MySQL在物理机和KVM环境下性能情况 压测标准 压测遵循单一变量原则,所有的对比都是只改变一个变量 ...
- MySQL优化聊两句
原文地址:http://www.cnblogs.com/verrion/p/mysql_optimised.html MySQL优化聊两句 MySQL不多介绍,今天聊两句该如何优化以及从哪些方面入手, ...
- Maven 整合FreeMarker使用
pom.xml <!-- freemarker jar --> <dependency> <groupId>org.freemarker</groupId&g ...
- NOIP2016纪录[那些我所追求的]
人生第一场正式OI [序] 2016-12-04 见底部 [Day -1] 2016-11-17 期中考试无心插柳柳成荫,考了全市第2班里第1(还不是因为只复习了不到两天考试),马上请了一个周的假准备 ...
- osi(open system interconnection)模型的通俗理解
OSI模型的理解: 以你和你女朋友以书信的方式进行通信为例. 1.物理层:运输工具,比如火车.汽车. 2.数据链路层:相当于货物核对单,表明里面有些什么东西,接受的时候确认一下是否正确(CRC检验). ...