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 在调用对 ...
随机推荐
- Sublime Text3安装JsHint
介绍 Sublime Text3使用jshint依赖Nodejs,SublimeLinter和Sublimelinter-jshint. NodeJs的安装省略. 安装SublimeLinter Su ...
- ASP.NET Core HTTP 管道中的那些事儿
前言 马上2016年就要过去了,时间可是真快啊. 上次写完 Identity 系列之后,反响还不错,所以本来打算写一个 ASP.NET Core 中间件系列的,但是中间遇到了很多事情.首先是 NPOI ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(74)-微信公众平台开发-自定义菜单
系列目录 引言 1.如果不借用Senparc.Weixin SDK自定义菜单,编码起来,工作量是非常之大 2.但是借助SDK似乎一切都是简单得不要不要的 3.自定义菜单无需要建立数据库表 4.自定义菜 ...
- CSS 特殊属性介绍之 pointer-events
首先看一下 MDN 上关于 pointer-events 的介绍: CSS属性 pointer-events 允许作者控制特定的图形元素在何时成为鼠标事件的 target.当未指定该属性时,SVG 内 ...
- 关于面试题 Array.indexof() 方法的实现及思考
这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了. 昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法. 对于想进大公 ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之目录导航
ASP.NET MVC with Entity Framework and CSS是2016年出版的一本比较新的.关于ASP.NET MVC.EF以及CSS技术的图书,我将尝试着翻译本书以供日后查阅. ...
- iOS逆向工程之Hopper中的ARM指令
虽然前段时间ARM被日本软银收购了,但是科技是无国界的,所以呢ARM相关知识该学的学.现在看ARM指令集还是倍感亲切的,毕竟大学里开了ARM这门课,并且做了不少的实验,当时自我感觉ARM这门课学的还是 ...
- PHP设计模式(六)原型模式(Prototype For PHP)
原型设计模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型设计模式简单的来说,顾名思义, 不去创建新的对象进而保留原型的一种设计模式. 缺点:原型设计模式是的最主要的缺点就 ...
- Android 关于ijkplayer
基于ijkplayer封装支持简单界面UI定制的视频播放器 可以解析ts格式的so库 怎样编译出可以解析ts等格式的so库?就是编译的时候需要在哪一步修改配置? 一些电视台的m3u8 CCTV1综合, ...
- iOS开源项目周报1222
由OpenDigg 出品的iOS开源项目周报第二期来啦.我们的iOS开源周报集合了OpenDigg一周来新收录的优质的iOS开发方面的开源项目,方便iOS开发人员便捷的找到自己需要的项目工具等. io ...