RunTime 运行时
简单介绍RunTime 运行时的用法
以下操作都需要导入头文件
#import <objc/message.h>
#pragma mark -- 发消息
//OC方法调用的本质就是让对象发消息
Person * p = [[Person alloc] init];
//[p eat];//底层是发消息
//对象方法
objc_msgSend(p, @selector(eat));
//类方法
[Person eat];
//类方法
objc_msgSend([Person class], @selector(eat));
#pragma mark -- 交换换方法的实现
目的:当你调用系统方法的时候,为系统自带的方法增加一些特有的功能!
//1、创建方法所属的类的分类
//创建URL的分类
+ (void)load
{//当这个类被加载进内存的时候调用这个方法,执行一次
//交换方法的实现 根据方法标号 找到对应的返回实现,交换实际执行的方法
Method systemURLWithString = class_getClassMethod([NSURL class], @selector(URLWithString:));
Method myURLWithString = class_getClassMethod([NSURL class], @selector(my_URLWithString:));
method_exchangeImplementations(systemURLWithString, myURLWithString);
}
//实现自己的方法
+ (nullable instancetype)my_URLWithString:(NSString *)URLString;
{
//实际会走系统的URLWithString方法
NSURL * url = [NSURL my_URLWithString:URLString];
if (url == nil) {
NSLog(@"url有问题");//做一些需要特殊处理的操作
return nil;
}
return url;
}
#pragma mark - 动态的增加方法
//一个类调用了一个没有实现的类方法时,就会调用这个方法
//没有返回值
void aaa(id self, SEL _cmd, id param) {
NSLog(@"%@ %@ %@", self, NSStringFromSelector(_cmd), param);
}
//sel:没有实现的方法
+ (BOOL)resolveClassMethod:(SEL)sel
{
if (sel == @selector(eat:)) {
// cls: 给哪一个类添加方法 SEL:方法标号 IMP:方法实现 types:方法类型
//"v@:" --> v代表void @代表id类型对象 :代表SEL
class_addMethod(self, sel, (IMP)aaa, "v@:@");
return YES;
}
return [super resolveClassMethod:sel];
}
//一个类调用了一个没有实现的对象方法时,就会调用这个方法
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
return return [super resolveInstanceMethod:sel];
}
#pragma mark - 动态的增加属性
// 1、创建分类
.h中增加属性
@property (nonatomic, copy) NSString * name;
// 注意:给分类增加属性只会生成setter和getter的方法声明,不会生成setter和getter的实现,也不会生成下划线开头的的成员变量,需要自己实现set和get方法,否则调用的时候就会崩溃,崩溃原因:找不到set和get的方法实现!!!解决办法:利用运行时,动态的实现set和get方法
- (void)setName:(NSString *)name
{
/*
* id object 给哪个对象的属性赋值
const void *key 属性对应的key
id value 设置属性值为value
objc_AssociationPolicy policy 使用的策略
objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)
*/
objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name
{
return objc_getAssociatedObject(self, @"name");
}
#pragma mark -- 查找子类方法
+ (NSArray *)findAllSubClassofClass:(Class)superClass
{
int count = objc_getClassList(NULL, 0);
NSMutableArray *output = [NSMutableArray array];
if (count <= 0) {//发生错误或者没有子类
@throw @"Couldn't retrieve Obj-C class-list";
return output;
}
Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * count);
count = objc_getClassList(classes, count);
for (int i = 0; i < count; ++i) {
if (superClass == class_getSuperclass(classes[i])) {//子类
[output addObject:classes[i]];
}
}
//释放C 语言的对象
free(classes);
return output;
}
更多内容--> 博客导航 每周一篇哟!!!
有任何关于iOS开发的问题!欢迎下方留言!!!或者邮件lieryangios@126.com 虽然我不一定能够解答出来,但是我会请教iOS开发高手!!!解答您的问题!!!
RunTime 运行时的更多相关文章
- runtime运行时
/** * Describes the instance variables declared by a class. * * @param cls The class to inspect. * @ ...
- iOS - OC RunTime 运行时
1.运行时的使用 向分类中添加属性 // 包含运行时头文件 #import <objc/runtime.h> /* void objc_setAssociatedObject(id obj ...
- iOS RunTime运行时(1):类与对象
Objective-C语言是一门动态语言,他将很多静态语言在编译和链接期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码更具有灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一下 ...
- RunTime运行时在iOS中的应用之UITextField占位符placeholder
RunTime运行时机制 runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的Objective-C代码中, 程序运行过程时, 其实最终 ...
- runtime运行时,类、对象、isa指针
先查看一段OC源码,关于类的定义: /// An opaque type that represents an Objective-C class. typedef struct objc_class ...
- iOS运行时Runtime浅析
运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...
- 【原】iOS动态性(五)一种可复用且解耦的用户统计实现(运行时Runtime)
声明:本文是本人 编程小翁 原创,转载请注明. 为了达到更好的阅读效果,强烈建议跳转到这里查看文章. iOS动态性是我的关于iOS运行时的系列文章,由浅入深,从理论到实践.本文是第5篇.有兴趣可以看看 ...
- iOS 运行时runtime控制私有变量以及私有方法
OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类.对象中的所有属性.方法,就算是私有方法以及私有属性都是可以动 ...
- Objective C运行时(runtime)
#import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...
随机推荐
- 搭建struct环境
昨天学习了struts,发现struts并不是struts2同一框架的升级,完全是属于两个框架.struts2是在freework的基础上进行封装的. 1.struts的环境搭载 (1)创建web ...
- .NET面试题系列[18] - 多线程同步(1)
多线程:线程同步 同步基本概念 多个线程同时访问共享资源时,线程同步用于防止数据损坏或发生无法预知的结果.对于仅仅是读取或者多个线程不可能同时接触到数据的情况,则完全不需要进行同步. 线程同步通常是使 ...
- 张高兴的 Windows 10 IoT 开发笔记:使用 ADS1115 读取模拟信号
考虑到 Raspberry Pi 读取模拟信号是很烦人的事情,更何况是在没人玩的 Windows 10 IoT 下,所以准备正儿八经的写点东西. 需求:使用 Raspberry Pi 读取输出模拟信号 ...
- JTable常见用法细则+设置某列可编辑+滚动表格
JTable常见用法细则 JTable是Swing编程中很常用的控件,这里总结了一些常用方法以备查阅.欢迎补充,转载请注明作者与出处. 一.创建表格控件的各种方式: 1) 调用无参构造函数. JTa ...
- 011一对一 唯一外键关联映射_单向(one-to-one)
² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库 ...
- 使用Spring MVC构建REST风格WEB应用
转自:http://fancy888.iteye.com/blog/1629120 对于运行在网络上的MIS系统而言,处理数据的是整个系统的主要任务,翻开程序我们可以看到,80%以上的代码都在处理数据 ...
- Spring Boot 声明式事务结合相关拦截器
我这项目的读写分离方式在使用ThreadLocal实现的读写分离在迁移后的偶发错误里提了,我不再说一次了,这次是有要求读写分离与事务部分要完全脱离配置文件,程序员折腾了很久,于是我就查了一下,由于我还 ...
- git上传本地项目到github
git软件下载地址:https://git-scm.com/download/ 1. 在GitHub上建立项目登录GitHub后,你可以在右边靠中那里找到一个按钮“New Repository”,点击 ...
- 脑洞大开--一条项目中常用的linux命令引发的经典算法题
小时候家里定了<读者>的月刊,里面记录一个故事:说有有个偏僻的乡村一日突然来了一个美女,她携着万贯家财子女在当地安家落户,成了当地的乡绅.她让她的子女世世代代的保守这个秘密,直到这个秘密不 ...
- getElementById和querySelector方法的区别
"querySelector 属于 W3C 中的 Selectors API 规范 .而 getElementsBy 系列则属于 W3C 的 DOM 规范" 1.区别 getXXX ...