简单介绍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. memcache 启动 failed to start

    以为是 端口冲突,到注册表中直接改了memcache的注册表,还是启动不了.memcache运行不了,还能咋办,看防火墙有没有阻止程序运行呗 勾上,我的windows 上的memcache 就可以运行 ...

  2. 抓包工具 Charles 使用心得

    前言 虽然实习工作还没有着落,但学习还是要继续的嘛,今天就来学习使用下 Mac 下截取网络封包的工具:Charles. 我想,如果你是个善于利用搜索引擎的人,那么在 Google 中输入「Charle ...

  3. 通过js给网页加上水印背景

    有些后端管理系统,因为业务逻辑的需要,需要加上水印,下面就是水印方法. function watermark(settings) { debugger; //默认设置 var defaultSetti ...

  4. angular控制器之间的传值

    每个controller都会有自己的scope,所有的scope都是属于 $rootScope的子或者子的子... 那么问题就好解决了,通过 $rootScope.$broadcast 广播的事件每个 ...

  5. Java中的Object、T(泛型)、?区别

    因为最近重新看了泛型,又看了些反射,导致我对Object.T(以下代指泛型).?产生了疑惑. 我们先来试着理解一下Object类,学习Java的应该都知道Object是所有类的父类,注意:那么这就意味 ...

  6. Hierarchy Viewer工具使用

    目前,在eclipse的ADT Android插件中,还不能启动Hierachy Viewer,但可以从Android SDK工具包中,通过命令行的方式可以启动,具体方法为,到Android SDK下 ...

  7. Spring Controller单元测试

    SpringMVC controller测试较简单,从功能角度划分,可分为两种.一种是调用请求路径测试,另一种是直接调用Controller方法测试. 调用请求路径测试 通过请求路径调用,请求需要经过 ...

  8. 2017-5-18 Repeater 重复器的使用

    Repeater - 重复器HeaderTemplate - 先执行,执行一次FooterTemplate - 最后执行,执行一次ItemTemplate - 在Header之后执行,有多少条数据绑定 ...

  9. 使用cnpm搭建私有NPM仓库 发布npm包

    关于如何使用cnpm搭建私有的npm仓库看这里→ http://blog.fens.me/nodejs-cnpm-npm/ 我本人还没有机会真正实践操作过,公司的npm仓库是我老大搭建的,我这里仅仅记 ...

  10. Ionic进行PC端Web开发时通过脚本压缩提高第一次加载效率

    1. 问题 1.1. 问题上下文描述: 基于Ionic进行PC端的Web应用开发: 使用Tomcat作为最终服务发布容器. 1.2. 问题描述: 编译后main.js的大小为4-6MByte.(集成第 ...