#import "DisplayAttribute.h"
#import <objc/runtime.h>
@implementation DisplayAttribute
/**
* 必备常识:
* Ivar : 成员变量 如果要是动态创建/修改/查看属性,可以使用Ivar
* Method : 成员方法 如果要是动态创建/修改/查看方法,可以使用Method
* 下面的例子教大家一些runtime简单的 查看类中属性和方法以及动态添加属性和方法和修改属性.
*/
/**
* 通过类的名字来获取类里面包含的所有属性
*
* @param className 类名(egs:UIView)
*/
- (void)getIvarsNameListWithClassName:(NSString *)className
{
//通过类的名字获取到类(egs:通过"学生"这个类的名字找到"学生"这个类)
Class ClassName = NSClassFromString(className);
//定义一个变量来存放遍历出来类里面属性的个数
unsigned int outConut = 0;
//查取类里面所有的属性
Ivar * vars = class_copyIvarList([ClassName class], &outConut);
//打印类里面有多少个属性
NSLog(@"%d",outConut);
//遍历类里面所有的属性 和 属性类型
for (int i = 0; i < outConut; i ++) {
//获取类里面属性的名字(将IVar变量转化为字符串)
const char * ivarName = ivar_getName(vars[i]);
//获取类里面属性的类型(获取IVar的类型)
const char * ivarType = ivar_getTypeEncoding(vars[i]);
//打印属性的名字和类型
printf("属性名字:%s 属性类型:%s\n",ivarName,ivarType);
/**
* 如果你想对这个类动态赋值修改的话,有两种
1:可以用KVC模式来进行赋值修改.不管它有没有在.h中声明(只要类中有这个属性),都可以赋值
* 例如:类中有一个属性为:"name",你这个时候就可以直接赋值了.
* [p1 setValue:@"东方_未明" forKey:@"name"];
2:Ivar name = vars[1];//找到对应的下表
* object_setIvar(p1, name, @"童星");
* 可以打印查看有没有修改成功
* NSLog(@"%@",[p1 valueForKey:@"name"]);
*/
}
/**
* 动态为类添加属性
*/
//通过类名获取到的类,创建一个对象
NSObject *p1 = [[[ClassName class] alloc] init];
//给"p1"这个对象动态添加一个属性:Key: name Vaule:lishijie,
static char name;
objc_setAssociatedObject(p1, &name, @"东方_未明", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//获取"p1"这个对象属性为"name"的lishijie
NSString * strName = objc_getAssociatedObject(p1, &name);
//打印动态添加的属性
NSLog(@"我是动态添加的属性:%@",strName);
}
/**
* 通过类的名字,查看类中所有的方法
*
* @param className 类的名字(egs:UIView)
*/
- (void)getMethodNameListWithClassName:(NSString *)className
{
//如果想添加方法直接调用就行了(只需要改一下类)
//添加方法
[self addMethod];
/**
* class_copyMethodList:获取所有方法
* method_getName:读取一个Method类型的变量,输出我们在上层中很熟悉的SEL
*
*/
//通过类的名字,获取到类
Class ClassName = NSClassFromString(className);
//定义一个变量来存放遍历出来类里面属性的个数
unsigned int count = 0;
//查取类里面所有的属性
Method * method = class_copyMethodList(ClassName, &count);
//遍历类里面所有的属性 和 属性类型
for (int i = 0; i < count; i ++) {
//获取类里面方法的名字
SEL methodName = method_getName(method[i]);
//获取类里面方法的类型
const char * methodType = method_copyReturnType(method[i]);
NSLog(@"方法名字:%@,方法类型:%s",NSStringFromSelector(methodName),methodType);
}
}
/**
class_addMethod的实现会覆盖父类的方法实现,但不会取代本类中已存在的实现,
如果本类中包含一个同名的实现,则函数会返回NO。
如果要修改已存在实现,可以使用method_setImplementation。
一个Objective-C方法是一个简单的C函数,它至少包含两个参数—self和_cmd。
所以,我们的实现函数(IMP参数指向的函数)至少需要两个参数
*/
//添加方法
- (void)addMethod
{
//例如: 给UIView添加一个方法
//给类添加一个方法
id p1 = [NSString new];
/**
* IMP指向的两个方法,必须实现(一个是函数的名字,一个是要实现的函数)
*
* @param class] 类
* @param @selectormethod1Name 函数的名字
* @param IMPmethod1 要实现的函数
* @param "v@" 函数参数的类型
*
* @return void
*
*/
class_addMethod([NSString class], @selector(method1Name), (IMP)method1, "v@");
//调用方法1
[p1 method1Name];
}
//------------------------添加方法需要实现的--------------------------//
//方法的名字,没有实际的作用,只是标识类里面有这个函数
- (void)method1Name
{
NSLog(@"我只是个method1名字");
}
//这个才是方法的实现 (根据method1Name 找到 method1 这个方法)
static void method1(id self, SEL _cmd, int a){
NSLog(@"我是动态添加的method");
}
runtime 基础篇(一)
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- Objective-C作为一门动态编译语言,会将编译和连接时要做的事情推迟到运行时。这代表着OC语言不仅仅需要一个...
- 前言 2016年6月9号开始Runtime NSObject方法 Cocoa中大多数对象是继承自NSObjectl...