偶遇runtime之关联、成员

我对runtime 并不精通,只是因为见的少而已,只是昨日 阿里百川的Demo和gitHub上下载项目遇见遇见过:

objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)和

objc_getAssociatedObject(<#id object#>, <#const void *key#>)  意在将“value”对象关联在“object”对象上,换句话说:“value”对象在“object”对象的整个生命周期中都是可用的。objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)参数中"object"为称为关联对象,"key"为成为关联关系的关键字、 唯一标示;"value"是被关联对象,"policy"为关联方针(是一枚举变量);那在什么情况下使用呢?

就目前所见:分类中@property声明的属性的setter、getter方法实现。我们知道在分类中使用@property声明的属性并不能正常的使用(在分类中@property不会生成_变量,也不会实现getter和setter方法,),那么我们只有自己手动实现了,可如下代码:

#import <Foundation/Foundation.h>

@interface NSObject (Sample)

@property (nonatomic,strong)NSString *kTitle;

@end

#import "NSObject+Sample.h"

#import <objc/runtime.h>

static const void *kKey = &kKey;

@implementation NSObject (Sample)

-(void)setKTitle:(NSString *)kTitle{

objc_setAssociatedObject(self, kKey, kTitle, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

-(NSString *)kTitle{

return objc_getAssociatedObject(self, kKey);

}

@end

这样我们就成功了为NSObject对象添加了一个属性(当然还缺个_kKey实例变量,但kTitle属性的点语法已经是可以正常使用了,可满足使用需求了)

在阿里百川多媒体的Demo里  是将一个方法里的临时变量关联到一个生命周期较长的对象上,以实现传值的功能。

当然,只要熟知其特性,在今后的编码中,只要有需求的,都是可以使用上的。

再来说一下runtime中 成员变量 Ivar:

先举个UIButton的例子

UIButton * btn = [[UIButton alloc]init];

unsigned int count = 0;

Ivar *varList = class_copyIvarList([btn class], &count);

 NSMutableArray *tmplist = [NSMutableArray array];

for (int i = 0 ; i < count; i++) {

Ivar ivar = varList[i];

const char *name = ivar_getName(ivar);

NSString *propertyName = [[NSString alloc]initWithUTF8String:name];

[tmplist addObject:propertyName];

  }

  NSLog(@"%@",tmplist);

这样你就可以在控制台上看到UIButton类声明过所有实例变量(一般前缀带有_)控制台输出如下:

  "_externalFlatEdge",

"_contentLookup",

"_contentEdgeInsets",

"_titleEdgeInsets",

"_imageEdgeInsets",

"_backgroundView",

"_floatingContentView",

"_contentBackdropView",

"_imageView",

"_titleView",

"_initialized",

"_lastDrawingControlState",

"_selectGestureRecognizer",

"_buttonFlags",

"_effectiveContentView",

"_maskAnimationView",

"_selectionView",

"_lazyTitleViewFont",

"_contentConstraints",

"_internalTitlePaddingInsets"

以上的变量中,有许多都是私有的,我们无法直接使用setter、getter方法或是点语法来对其值进行存取的,只有使用kvc可以对私有属性的值进行存取:

  在上面代码的for循环中添加  id obj = [btn valueForKey:propertyName]; 执行 代码  却会导致程序崩溃。。。

  控制台给出的原因是‘[<UIButton 0x7fd50257cec0> valueForUndefinedKey:]:

  回到上面列表中,细想来,便知:有些实例变量是通过属性声明生成的,有些是直接声明为实例变量的,

  再看kvc 中  setValue:<#(nullable id)#> forKey:<#(nonnull NSString *)#>  与  valueForKey:<#(nonnull NSString *)#> 的方法存取实例的属性的值 是通过访问其setter、getter方法,如果仅仅只是声明为实例变量,没有setter、getter方法,则会调用 setValue:<#(nullable id)#> forUndefinedKey:<#(nonnull NSString *)#>与 valueForUndefinedKey:<#(nonnull NSString *)#> 方法,而这两个方法往往需要我们自己实现,一般而言我们对仅声明为实例变量的没有多少需求,所以我们对forUndefinedKey 这两个方法的实现 一般内面没有什么代码,常见如下:

-(void)setValue:(id)value forUndefinedKey:(NSString *)key{ }

-(id)valueForUndefinedKey:(NSString *)key { return nil;}

--runtime 里面其实还有很多值得挖掘的知识;

  

时间: 2024-08-27 12:54:42

偶遇runtime之关联、成员的相关文章

runtime第二部分成员变量和属性

接上一篇 http://www.cnblogs.com/ddavidXu/p/5912306.html 转载来源http://www.jianshu.com/p/6b905584f536 http://southpeak.github.io/2014/10/30/objective-c-runtime-2/ 比较实用的内容都用颜色的字标记,并配有代码,并在末尾放上代码demo. 类型编码(Type Encoding) Objective-C不支持long double类型.@encode(lon

IOS Runtime属性关联实现表格编辑文本

要实现在表格里编辑文本, 表格让我想到了CollectionView,文本让我想起TextView, 做之前想了好久怎么样来获得编辑的是哪个TextView,要获取对应的IndexPath啊,想着之前Cell中的按钮用block来实现,在自定义的Cell中加一个属性存IndexPath,可想着就一个TextView要自定义写一个类这样也未免太麻烦了.正好突然想到之前听过的属性管理,自己就凑着这个机会用了下,赶脚还不错. 有时候类的实例可能是某种机制所创建,而开发者无法令这种机制创建出自己所写的子

Objective-C Runtime 运行时之二:成员变量与属性

类型编码(Type Encoding) 作为对Runtime的补充,编译器将每个方法的返回值和参数类型编码为一个字符串,并将其与方法的selector关联在一起.这种编码方案在其它情况下也是非常有用的,因此我们可以使用@encode编译器指令来获取它.当给定一个类型时,@encode返回这个类型的字符串编码.这些类型可以是诸如int.指针这样的基本类型,也可以是结构体.类等类型.事实上,任何可以作为sizeof()操作参数的类型都可以用于@encode(). 在Objective-C Runti

iOS runtime实战应用:关联对象

在开始之前建议先阅读iOS runtime的基础理解篇:iOS内功篇:runtime 有筒子在面试的时候,遇到这样一个问题:"如何給NSArray添加一个属性(不能使用继承)",筒子立马蒙逼了,不能用继承,难道用分类?但是分类貌似只能添加方法不能添加属性啊,筒子百思不得其解,直到后来接触到了runtime才恍然大悟. 什么是关联对象 关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上.举个例子:xiaoming是Person类的一个实例,他的dog(一个OC对象)通过一根

刨根问底Objective-C Runtime(4)- 成员变量与属性

http://chun.tips/blog/2014/11/08/bao-gen-wen-di-objective[nil]c-runtime(4)[nil]-cheng-yuan-bian-liang-yu-shu-xing/ 上一篇笔记讲述了objc runtime中消息和Category的细节,本篇笔记主要是讲述objc runtime的 成员变量和属性. 习题内容 下面代码会? Compile Error / Runtime Crash / NSLog…? @interface Sark

runtime比较全面的总结

类和对象 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等. 这种特性意味着Objective-C不仅需要一个编译器,还需要一个运行时系统来执行编译的代码.对于Objective-C来说,这个运行时系统就像一个操作系统一样:它让所有的工作可以正常的运行.这个运行时系统即Objc Runtime.Objc Runtime其实是一个Ru

Runtime ----- 带你上道

在IOS开发和学习过程中,我们经常会接触到一个词: Runtime  .很多开发者对之既熟悉又陌生,基本都是浅尝辄止,达不到灵活使用的水平(话说开发中也确实不经常用..)本文和大家一起研究一下,Runtime到底是什么,还有他的一些应用场景,毕竟Runtime是OC动态特性的核心,熟练掌握它可以帮助我们更好的控制类的属性及方法,编写出更高效的代码. 一.什么是Runtime  不管你之前如何理解的Runtime,先把他扔一边,我们从头梳理一下: 1.有一种大气而准确的说法 : Objective

iOS:runtime最全的知识总结

runtime 完整总结 好东西,应该拿出来与大家分享... 南峰子博客地址:http://southpeak.github.io/blog/categories/ios/ 原文链接:http://www.jianshu.com/p/6b905584f536 类和对象 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一个方法的实现等.这种特性意味着

iOS:学习runtime的理解和心得

http://www.cocoachina.com/ios/20150901/13173.html 作者:兴宇是谁 授权本站转载. Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门语言所必需理解的东西.最近在学习Runtime,有自己的一些心得,整理如下, 一为 查阅方便 二为 或许能给他人一些启发, 三为 希望得到大家对这篇整理不足之处的一些指点. 什么是Runtime 我们写的代码在程序运行过程中都会被转化成runtime的C代码执行,例如[target doSometh