简单介绍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. python django 实现验证码的功能

    我也是刚学Python  Django不久很多都不懂,所以我现在想一边学习一边记录下来然后大家一起讨论! 验证码功能一开始我在网上找了很多的demo但是我在模仿他们写的时候,发现在我的版本上根本就不能 ...

  2. .Net程序员学用Oracle系列(10):系统函数(中)

    1.四大转换函数 1.1.TO_CHAR 1.2.TO_NUMBER 1.3.TO_DATE 1.4.CAST 2.两大近似值函数 2.1.ROUND 2.2.TRUNC 3.正则函数 3.1.正则函 ...

  3. swift闭包中解决循环引用的问题

    swift中可以通过三种方法解决循环引用的问题 利用类似oc方法解决循环引用weak var weakSelf = self weak var weakSelf = self loadData = { ...

  4. JVM、GC与HashMap

    阿里巴巴突然来了个面试邀请电话,问了些java底层的东西,不知所措,所以专门花了些时间做了下学习,顺便记录下,好记性不如烂笔头. 一.对JAVA的垃圾回收机制(GC)的理解 不同于C/C++需要手工释 ...

  5. 从零开始——PowerShell应用入门(全例子入门讲解)

    学习一门技术,不止要会,还要善用,例子就是带你快速入门的最佳利器.本文就是要用例子,不,大量的例子来带你走进PowerShell应用世界. 本文主要介绍一些PowerShell入门的基础知识,对技术小 ...

  6. python 2.7中urllib 2 与python 3.5中 urllib的区别。

    python 3.x中urllib库和urilib2库合并成了urllib库. 其中urllib2.urlopen()变成了urllib.request.urlopen() urllib2.Reque ...

  7. PHP基础入门(二)---入门必备哦!

    前言 在上一章中,我们初步了解了PHP的网页基础和PHP的入门基础,今天继续给大家分享更多有关PHP的知识. 理论知识看起来可能比较枯燥一些,但是我们的实践(敲代码)毕竟离不开它. 只有理论与实践相结 ...

  8. 【webpack】webpack-dev-server生猛上手——让我们来搭一个webpack的微服务器吧!

      [前言]:因为最近在搞百度地图API的时候到了webpack的externals,才发现我之前都只是用webpack做一些搭建完项目后的"收尾工作"--即打包,而没有把它纳入到 ...

  9. 一天搞定CSS:背景background--03

    背景分为-背景颜色和背景图片 1.背景属性 2.背景颜色 代码演示: <!DOCTYPE html> <html> <head> <meta charset= ...

  10. 网络编程应用:基于TCP协议【实现对象传输】--练习

    要求: 基于TCP协议实现,客服端向服务器发送一个对象 服务器接受并显示用户信息 ,同时返回给客户端 "数据已收到" 建一个Student类,属性:name age Student ...