iOS RunTime分析

1、什么是RunTime

RunTime即运行时,objective-c是一种运行时的语言,什么是运行时呢,运行时就是在程序运行的时候才去确定我们的对象的类型和需要调用类和对象相对应的方法。

2、RunTime的用法

RunTime是在我们程序运行的时候才去确定我们的对象类型,和调用类与对象相对应的方法,属性等,所以我们可以在程序运行时去修改对象的属性,方法,修改类。

3、RunTime的体现
Animal *a = [[Animal alloc] init];  
[a eat];//eat是一个实例方法
//底层运行的状态
[a performSelector:@selector(eat)];
objc_msgSend(a,@selector(eat));
//类方法也是一样
[Animal eat];
//底层运行的状态
Class animalClass = [Animal class];
[[Animal class] performSelector(eat)];
objc_msgSend(animalClass,@selector(eat));

从我们调用方法到底层运行的顺序是:实例方法的调用,然后是底层进行performSelector:然后到objc_msgSend。

4、RunTime的使用场景
  • 1、使用RunTime进行方法的调换。
    很常见的一个例子,在我们进行图片加载的时候,我们有这样一个需求,在加载图片之后判断这个图片是否为空,如果为空就输出error。我们首先想到就是使用分类来做,使用分类来做是没有问题的,前提是你还没有写多少代码,如果你的项目很庞大,不可能全部都重新修改你加载图片的方法吧,所以说使用分类不是不行,而是很不方便,那么我们需要怎么做呢?我们要坐的就是在分类里面对我们的方法进行替换。首先我们需要写一个我们用来替换原本加载图片的方法的方法。
+(UIImage *)judgeImageName:(NSString *)name{
  UIImage \*image = [UIImage imageNamed:name];
  if (image == nil) {
      NSLog(@"error");
  }
  return image;
}  

//然后在分类的+(void)load;方法进行方法的替换

+(void)load{
  Method imageNamedMethod = class_getClassMethod([UIImage class],@selector(imageNamed));
  Method judgeimageNamedMethod = class_getClassMethod([UIImage class],@selector(judgeImageName));
  Method_exchangeImplementations(imageNamedMethod,judgeimageNamedMethod);
}

需要注意的是,我们使用了这种做法来替换方法之后不能去调用我们在分类中写的方法了,原因是你调用这个方法,这个方法调用原来的方法,原来的方法又去调用我们写的方法,这样的话就是一个死循环。

  • 2、使用RunTime添加属性
    分类是默认不能添加属性的,就算我们用@property声明了一个属性,该属性的set和get只会声明而不会实现。但是我们可以使用RunTime来为分类添加属性。
@property (nonatomic, strong)NSString *age
-(void)setAge:(NSString *)name{
objc_setAssociatedObject(self,@"age",age,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

objc_setAssociatedObject中的参数:
第一个参数为在哪里添加这个属性,这里就是self
第二个参数为属性名
第三个参数为属性值
第四个参数为属性的形式,一般有以下几种

OBJC_ASSOCIATION_ASSIGN = 0, //弱对象
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //强引用,非原子性
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //指定对象赋值,非原子性
OBJC_ASSOCIATION_RETAIN = 01401, //强引用, 原子性
OBJC_ASSOCIATION_COPY = 01403   //指定对象赋值,原子性
}
-(NSString *)age{
objc_getAssociatedObject(self,@"age");
}

objc_getAssociatedObject中的参数:
第一个参数为获取哪个对象里面关联的属性。
第二个参数为什么属性,其实就是属性名。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,092评论 19 139
  • 对于从事 iOS 开发人员来说,所有的人都会答出【runtime 是运行时】什么情况下用runtime?大部分人能...
    梦夜繁星阅读 9,111评论 7 64
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,883评论 0 9
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 14,023评论 6 13
  • 《登楼望月》 轻尘 海水尚有涯,相思渺无畔。 华胥相思引,不解相思半。 孤楼邀月影,弦断相思肠...
    黄小黑阅读 2,656评论 9 10

友情链接更多精彩内容