简单介绍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 运行时的更多相关文章

  1. runtime运行时

    /** * Describes the instance variables declared by a class. * * @param cls The class to inspect. * @ ...

  2. iOS - OC RunTime 运行时

    1.运行时的使用 向分类中添加属性 // 包含运行时头文件 #import <objc/runtime.h> /* void objc_setAssociatedObject(id obj ...

  3. iOS RunTime运行时(1):类与对象

    Objective-C语言是一门动态语言,他将很多静态语言在编译和链接期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码更具有灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一下 ...

  4. RunTime运行时在iOS中的应用之UITextField占位符placeholder

    RunTime运行时机制 runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的Objective-C代码中, 程序运行过程时, 其实最终 ...

  5. runtime运行时,类、对象、isa指针

    先查看一段OC源码,关于类的定义: /// An opaque type that represents an Objective-C class. typedef struct objc_class ...

  6. iOS运行时Runtime浅析

    运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...

  7. 【原】iOS动态性(五)一种可复用且解耦的用户统计实现(运行时Runtime)

    声明:本文是本人 编程小翁 原创,转载请注明. 为了达到更好的阅读效果,强烈建议跳转到这里查看文章. iOS动态性是我的关于iOS运行时的系列文章,由浅入深,从理论到实践.本文是第5篇.有兴趣可以看看 ...

  8. iOS 运行时runtime控制私有变量以及私有方法

    OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法.利用runtime机制让我们可以在程序运行时动态修改类.对象中的所有属性.方法,就算是私有方法以及私有属性都是可以动 ...

  9. Objective C运行时(runtime)

    #import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...

随机推荐

  1. React入门---可复用组件-10

    主要对props更多重要的特性进行学习; 还是用之前代码, index.js代码为: var React = require('react'); var ReactDOM = require('rea ...

  2. BattleInfo

    private Dictionary<string, UILabel> mLabels; private Dictionary<string,UISprite> mSprite ...

  3. kafka 0.8.2 消息生产者 producer

    package com.hashleaf.kafka; import java.util.Properties; import kafka.javaapi.producer.Producer; imp ...

  4. oracle配置odbc数据源

    今天配置oracle数据源心得: 1.需安装oracle客户端,若校验报错,将杀毒软件全部退出之后再重新安装: 2.安装完成后,运行odbcad32(64位),在odbc界面可找到相应驱动: 3.客户 ...

  5. 从零开始理解JAVA事件处理机制(2)

    第一节中的示例过于简单<从零开始理解JAVA事件处理机制(1)>,简单到让大家觉得这样的代码简直毫无用处.但是没办法,我们要继续写这毫无用处的代码,然后引出下一阶段真正有益的代码. 一:事 ...

  6. 通过wireshark学习Traceroute命令(UDP,ICMP协议)

    traceroute: 通过TTL限定的ICMP/UDP/TCP侦测包来发现从本地主机到远端目标主机之间的第三层转发路径.用来调试网络连接性和路由问题. mtr: traceroute的一个变种,能根 ...

  7. eclipse 创建maven 项目 动态web工程报错

    Eclipse 创建maven 项目 动态web工程 注:Eclipse版本为(Version: Mars.1 Release (4.5.1))maven版本为(apache-maven-3.3.9) ...

  8. 定位--position属性

    一.定位--position属性 1.static:默认值 没有定位--以标准文档流方式显示 2.relative:相对定位--相对自身原来的位置进行偏移(top left right bottom) ...

  9. 模拟对象测试——EasyMock

    一.EasyMock 使用动态代理实现模拟对象创建,一般可以满足以下测试需求 1.要测试的模块依赖于其它自己控制不了的模块,如第三方服务,其它组员在开发的服务等,它们都没办法配合你来测试: 2.涉及到 ...

  10. asp.net core 教程(六)-中间件

    Asp.Net Core-中间件 在这一章,我们将了解如何设置中间件.中间件技术在 ASP.NET Core中控制我们的应用程序如何响应 HTTP 请求.它还可以控制应用程序的异常错误,这是一个在如何 ...