[转载]复习总结 Runtime
//
// bttViewController.m
// Runtime
//
// Created by 为童沉沦 on 2022/4/12.
//
#import "ViewController.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import <dlfcn.h> /// 动态链接库头文件
#import <mach-o/ldsyms.h> ///内核动态系统库头文件
@interface ViewController ()<UITableViewDelegate>
{
NSString *_runtime1;
__weak id _bttID;
}
@property (nonatomic ,copy) NSString *logic;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - 解除IMP与Block关联
- (void)btt_imp_removeBlock {
//参数:IMP
//返回:BOOL
BOOL result = imp_removeBlock(class_getMethodImplementation(self.class, NSSelectorFromString(@"btt_method")));
NSLog(@"btt_imp_removeBlock:%d",result);
}
#pragma mark - 通过IMP获取Block
- (void)btt_imp_getBlock {
void (^blcok) (NSString *) = ^(NSString *str) {
NSLog(@"btt_imp_implementationWithBlock:%@",str);
};
//参数:IMP
//返回:block
void (^result) (NSString *) = imp_getBlock(imp_implementationWithBlock(blcok));
result(@"hello word");
}
#pragma mark - 通过block获取一个方法的实现
- (void)btt_imp_implementationWithBlock {
void (^blcok) (NSString *) = ^(NSString *str) {
NSLog(@"btt_imp_implementationWithBlock");
};
//参数:block
//返回:IMP
IMP result = imp_implementationWithBlock(blcok);
result();
}
#pragma mark - 设置突变处理函数
- (void)btt_objc_setEnumerationMutationHandler {
//参数:函数指针
objc_setEnumerationMutationHandler(enumerationMutationHandler);
}
void enumerationMutationHandler(id obj) {
NSLog(@"enumerationMutationHandler");
}
#pragma mark - 检测到突变时,编译器将插入次函数 并且调用objc_setEnumerationMutationHandler设置的回调函数,如果没有设置,则会崩溃
- (void)btt_objc_enumerationMutation {
//参数:id
objc_enumerationMutation(self);
}
#pragma mark - 获取属性的属性列表
- (void)btt_property_copyAttributeList {
objc_property_t t = class_getProperty(self.class, [@"logic" UTF8String]);
unsigned int count = 0;
//参数:1.objc_property_t 2.unsigned int *
//返回:属性的属性列表
objc_property_attribute_t *result = property_copyAttributeList(t, &count);
for (int i = 0; i < count; i ++) {
objc_property_attribute_t t = result[i];
NSLog(@"btt_property_copyAttributeList:%@",[NSString stringWithUTF8String:t.name]);
}
free(result);
}
#pragma mark - 获取属性的指定属性的值
- (void)btt_property_copyAttributeValue {
objc_property_t t = class_getProperty(self.class, [@"logic" UTF8String]);
//参数:1.objc_property_t 2.属性的属性
//返回:属性的属性的值
char *result = property_copyAttributeValue(t, [@"T" UTF8String]);
NSLog(@"btt_property_copyAttributeValue:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取属性的属性
- (void)btt_property_getAttributes {
objc_property_t t = class_getProperty(self.class, [@"logic" UTF8String]);
//参数:objc_property_t
//返回:属性的属性
const char *result = property_getAttributes(t);
NSLog(@"btt_property_getAttributes:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取属性的名称
- (void)btt_property_getName {
objc_property_t t = class_getProperty(self.class, [@"logic" UTF8String]);
//参数:objc_property_t
//返回:属性的名称
const char *result = property_getName(t);
NSLog(@"btt_property_getName:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 判断一个协议是否遵循另一个协议
- (void)btt_protocol_conformsToProtocol {
Protocol *pro1 = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
Protocol *pro2 = objc_getProtocol([@"UIScrollViewDelegate" UTF8String]);
//参数:Protocol
//返回:BOOL
BOOL result = protocol_conformsToProtocol(pro1, pro2);
NSLog(@"btt_protocol_conformsToProtocol:%d",result);
}
#pragma mark - 获取协议中采用的协议列表
- (void)btt_protocol_copyProtocolList {
Protocol *pro = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
unsigned int count = 0;
//参数:1.Protocol 2.unsigned int *
//返回:协议列表
Protocol __unsafe_unretained **result = protocol_copyProtocolList(pro, &count);
for (int i = 0; i < count; i ++) {
Protocol *p = result[i];
NSLog(@"btt_protocol_copyProtocolList:%@",p);
}
free(result);
}
#pragma mark - 获取协议中指定的属性
- (void)btt_protocol_getProperty {
Protocol *pro = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
//参数:1.Protocol 2.属性名称 3.是否为必须方法 4.是否为实例方法
objc_property_t result = protocol_getProperty(pro, [@"" UTF8String], YES, YES);
NSLog(@"btt_protocol_getProperty:%p",result);
}
#pragma mark - 获取协议的属性列表
- (void)btt_protocol_copyPropertyList {
Protocol *pro = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
unsigned int count = 0;
//参数:1.Protocol 2.unsigned int *
//返回:协议的属性列表
objc_property_t *result = protocol_copyPropertyList(pro, &count);
for (int i = 0; i < count; i ++) {
objc_property_t t = result[i];
NSLog(@"btt_protocol_copyPropertyList:%p",t);
}
}
#pragma mark - 获取协议中指定方法的描述结构体
- (void)btt_protocol_getMethodDescription {
Protocol *pro = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
//参数:1.Protocol 2.SEL 3.是否为必须方法 4.是否为实例方法
struct objc_method_description result = protocol_getMethodDescription(pro, NSSelectorFromString(@"tableView:willDisplayCell:forRowAtIndexPath:"), NO, YES);
NSLog(@"btt_protocol_getMethodDescription:%p",result.name);
}
#pragma mark - 获取满足条件的协议的方法列表
- (void)btt_protocol_copyMethodDescriptionList {
Protocol *pro = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
unsigned int count = 0;
//参数:1.Protocol 2.是否为必须方法 3.是否为实例方法 4.unsigned int *
struct objc_method_description *result = protocol_copyMethodDescriptionList(pro, NO, YES, &count);
for (int i = 0; i < count; i ++) {
struct objc_method_description des = result[i];
NSLog(@"btt_protocol_copyMethodDescriptionList:%p",des.name);
}
}
#pragma mark - 判断俩个协议是否相等
- (void)btt_protocol_isEqual {
Protocol *pro1 = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
Protocol *pro2 = objc_getProtocol([@"UITableViewDataSource" UTF8String]);
//参数:Protocol
//返回:BOOL
BOOL result = protocol_isEqual(pro1, pro2);
NSLog(@"btt_protocol_isEqual:%d",result);
}
#pragma mark - 获取协议的名称
- (void)btt_protocol_getName {
Protocol *pro = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
//参数:协议Protocol
//返回:协议名称
const char *result = protocol_getName(pro);
NSLog(@"btt_protocol_getName:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 向协议中添加属性
- (void)btt_protocol_addProperty {
Protocol *pro = objc_allocateProtocol([@"LGProtocol" UTF8String]);
objc_property_attribute_t type = { "T", "@\"NSString\"" };
objc_property_attribute_t ownership = { "C", "" }; // C = copy
objc_property_attribute_t backingivar = { "V", "_logic" };
objc_property_attribute_t attrs[] = { type, ownership, backingivar };
//参数:1.协议Protocol 2.属性的名称 3.属性的属性 4.属性的属性的个数 5.是否为协议的必须方法 6.填YES
protocol_addProperty(pro, [@"logic" UTF8String], attrs, 3, YES, YES);
}
#pragma mark - 向协议中添加协议
- (void)btt_protocol_addProtocol {
Protocol *pro1 = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
Protocol *pro2 = objc_allocateProtocol([@"LGProtocol" UTF8String]);
//参数:1.要添加到的协议 2.要添加的协议
protocol_addProtocol(pro1, pro2);
}
#pragma mark - 向协议添加方法
- (void)btt_protocol_addMethodDescription {
Protocol *pro = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
//参数:1.协议Protocol 2.SEL 3.方法名称 4.是否为协议必须方法 5.是否为实例方法
protocol_addMethodDescription(pro, NSSelectorFromString(@"btt_method"), [@"lgProtocolMethod" UTF8String], YES, YES);
}
#pragma mark - 注册协议
- (void)btt_objc_registerProtocol {
Protocol *result = objc_allocateProtocol([@"LGProtocol" UTF8String]);
//参数:协议Protocol
objc_registerProtocol(result);
}
#pragma mark - 创建协议
- (void)btt_objc_allocateProtocol {
//参数:协议的名称
//返回:协议
Protocol *result = objc_allocateProtocol([@"LGProtocol" UTF8String]);
NSLog(@"btt_objc_allocateProtocol:%@",result);
}
#pragma mark - 获取所有的协议列表
- (void)btt_objc_copyProtocolList {
unsigned int count = 0;
//参数:unsigned int *
//返回:所有的协议列表
Protocol __unsafe_unretained **result = objc_copyProtocolList(&count);
for (int i = 0; i < count; i ++) {
Protocol *pro = result[i];
NSLog(@"btt_objc_copyProtocolList:%@",pro);
}
}
#pragma mark - 获取指定的协议
- (void)btt_objc_getProtocol {
//参数:协议名称
//返回:协议
Protocol *result = objc_getProtocol([@"UITableViewDelegate" UTF8String]);
NSLog(@"btt_objc_getProtocol:%@",result);
}
#pragma mark - 判断俩个选择器是否相等
- (void)btt_sel_isEqual {
SEL sel1 = NSSelectorFromString(@"btt_method1");
SEL sel2 = NSSelectorFromString(@"btt_method2");
//参数:SEL
//返回:BOOL
BOOL result = sel_isEqual(sel1, sel2);
NSLog(@"btt_sel_isEqual:%d",result);
}
#pragma mark - 注册方法
- (void)btt_sel_getUid {
//参数:const char *
//返回:SEL
SEL result = sel_getUid([@"lglglg" UTF8String]);
NSLog(@"sel_getUid:%p",result);
}
#pragma mark - 注册方法
- (void)btt_sel_registerName {
//参数:const char *
//返回:SEL
SEL result = sel_registerName([@"lglglg" UTF8String]);
NSLog(@"btt_sel_registerName:%p",result);
}
#pragma mark - 获取方法的名称
- (void)btt_sel_getName {
SEL sel = NSSelectorFromString(@"btt_method");
//参数:SEL
//返回:方法的名称
const char *result = sel_getName(sel);
NSLog(@"btt_sel_getName:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取指定库或框架中的所有类的名称
- (void)btt_objc_copyClassNamesForImage {
unsigned int outCount = 0;
Dl_info info;
dladdr(&_mh_execute_header, &info);
//参数:1.库或者框架 2.unsigned int *
//返回:指定库或框架中的所有类的名称
const char **result = objc_copyClassNamesForImage(info.dli_fname, &outCount);
for (int i = 0; i < outCount; i ++) {
const char *c = result[i];
NSLog(@"btt_objc_copyClassNamesForImage:%@",[NSString stringWithUTF8String:c]);
}
}
#pragma mark - 获取类源自的动态库的名称
- (void)btt_class_getImageName {
//参数:类Class
//返回:源自的动态库的名称
const char *result = class_getImageName(self.class);
NSLog(@"btt_class_getImageName:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取所有的objc框架和动态库
- (void)btt_objc_copyImageNames {
unsigned int a = 0;
//参数:unsigned int *
//返回:C字符串数组
const char **result = objc_copyImageNames(&a);
for (int i = 0; i < a; i ++) {
const char *c = result[i];
NSLog(@"btt_objc_copyImageNames:%@",[NSString stringWithUTF8String:c]);
}
}
#pragma mark - 交换俩种方法的实现
- (void)btt_method_exchangeImplementations {
Method method1 = class_getInstanceMethod(self.class, @selector(btt_method1));
Method method2 = class_getInstanceMethod(self.class, @selector(btt_method2));
//参数:Method
method_exchangeImplementations(method1, method2);
[self btt_method1];
[self btt_method2];
}
#pragma mark - 设置方法的实现
- (void)btt_method_setImplementation {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
IMP imp = class_getMethodImplementation(self.class, @selector(btt_method1));
//参数:1.Method 2.IMP
//返回:方法的先前实现
IMP result = method_setImplementation(method, imp);
NSLog(@"btt_method_setImplementation:%p",result);
result();
[self btt_method];
}
#pragma mark - 获取方法的结构体
- (void)btt_method_getDescription {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:Method
//返回:方法的结构体
struct objc_method_description *result = method_getDescription(method);
NSLog(@"btt_method_getDescription:%p",result);
}
#pragma mark - 获取单个参数的类型
- (void)btt_method_getArgumentType {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
char result[10];
//参数:1.Method 2.参数索引 3.char数组 4.char数组的长度
method_getArgumentType(method, 0, result, sizeof(result));
NSLog(@"btt_method_getArgumentType:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取方法参数的数量
- (void)btt_method_getNumberOfArguments {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:Method
//返回:参数的个数
unsigned int result = method_getNumberOfArguments(method);
NSLog(@"btt_method_getNumberOfArguments:%d",result);
}
#pragma mark - 获取方法的返回值类型
- (void)btt_method_getReturnType {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:1.Method 2.char数组 3.char数组的长度
char result[10];
method_getReturnType(method,result,sizeof(result));
NSLog(@"btt_method_getReturnType:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取方法的单个参数类型
- (void)btt_method_copyArgumentType {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:1.Method 2.unsigned int参数索引
//返回:参数类型
char *result = method_copyArgumentType(method, 0);
NSLog(@"btt_method_copyReturnType:%@",[NSString stringWithUTF8String:result]);
free(result);
}
#pragma mark - 获取方法的返回值类型
- (void)btt_method_copyReturnType {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:Method
//返回:方法的返回值类型
char *result = method_copyReturnType(method);
NSLog(@"btt_method_copyReturnType:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取描述方法的参数和返回值类型的字符串
- (void)btt_method_getTypeEncoding {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:Method
//返回:描述方法的参数和返回值类型的字符串
const char *result = method_getTypeEncoding(method);
NSLog(@"btt_method_getTypeEncoding:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取方法的实现
- (void)btt_method_getImplementation {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:Mothod
//返回:IMP指针
IMP result = method_getImplementation(method);
NSLog(@"btt_method_getImplementation:%p",result);
}
#pragma mark - 获取方法名称
- (void)btt_method_getName {
Method method = class_getInstanceMethod(self.class, @selector(btt_method));
//参数:Mothod
//返回:SEL指针
SEL result = method_getName(method);
NSLog(@"btt_method_getName:%p",result);
}
#pragma mark - 删除关联
- (void)btt_objc_removeAssociatedObjects {
//参数:关联的对象
objc_removeAssociatedObjects(self);
}
#pragma mark - 获取关联的值
- (void)btt_objc_getAssociatedObject {
//参数:1.关联的对象 2.key
//返回:关联的值
id result = objc_getAssociatedObject(self, [@"LGKey" UTF8String]);
NSLog(@"btt_objc_getAssociatedObject:%@",result);
}
#pragma mark - 设置关联
- (void)btt_objc_setAssociatedObject {
/**
policy:关联策略。有五种关联策略。
OBJC_ASSOCIATION_ASSIGN 等价于 @property(assign)。
OBJC_ASSOCIATION_RETAIN_NONATOMIC等价于 @property(strong, nonatomic)。
OBJC_ASSOCIATION_COPY_NONATOMIC等价于@property(copy, nonatomic)。
OBJC_ASSOCIATION_RETAIN等价于@property(strong,atomic)。
OBJC_ASSOCIATION_COPY等价于@property(copy, atomic)。
*/
//参数:1.要关联的对象 2.全局唯一KEY 3.关联的obj 4.关联策略policy
objc_setAssociatedObject(self, [@"LGKey" UTF8String], @"123456", OBJC_ASSOCIATION_COPY_NONATOMIC);
}
#pragma mark - 获取实例变量的偏移量
- (void)btt_ivar_getOffset {
Ivar ivar = class_getInstanceVariable(self.class, [@"_logic" UTF8String]);
//参数:Ivar
//返回:实例变量的类型
ptrdiff_t result = ivar_getOffset(ivar);
NSLog(@"btt_ivar_getOffset:%td",result);
}
#pragma mark - 获取实例变量的类型
- (void)btt_ivar_getTypeEncoding {
Ivar ivar = class_getInstanceVariable(self.class, [@"_logic" UTF8String]);
//参数:Ivar
//返回:实例变量的类型
const char *result = ivar_getTypeEncoding(ivar);
NSLog(@"btt_ivar_getTypeEncoding:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取实例变量名称
- (void)btt_ivar_getName {
Ivar ivar = class_getInstanceVariable(self.class, [@"_logic" UTF8String]);
//参数:Ivar
//返回:实例变量的名称
const char *result = ivar_getName(ivar);
NSLog(@"btt_ivar_getName:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取指定类的元类定义
- (void)btt_objc_getMetaClass {
//参数:类的名称
//返回:类Class
id result = objc_getMetaClass([@"ViewController" UTF8String]);
NSLog(@"objc_getMetaClass:%@",result);
}
#pragma mark - 获取指定类的类定义
- (void)btt_objc_getRequiredClass {
//参数:类的名称
//返回:类Class
Class result = objc_getRequiredClass([@"ViewController" UTF8String]);
NSLog(@"btt_objc_getRequiredClass:%@",result);
}
#pragma mark - 获取指定类的类定义
- (void)btt_objc_getClass {
//参数:类的名称
//返回:类Class
Class result = objc_getClass([@"ViewController" UTF8String]);
NSLog(@"btt_objc_getClass:%@",result);
}
#pragma mark - 获取指定类的类定义
- (void)btt_objc_lookUpClass {
//参数:类的名称
//返回:类Class
Class result = objc_lookUpClass([@"ViewController" UTF8String]);
NSLog(@"btt_objc_lookUpClass:%@",result);
}
#pragma mark - 获取已注册的类
- (void)btt_objc_copyClassList {
unsigned int outCount;
//参数:整数指针
//返回:已注册的类的指针列表
Class *result = objc_copyClassList(&outCount);
for (int i = 0; i < outCount; i++) {
NSLog(@"btt_objc_copyClassList:%s", class_getName(result[i]));
}
free(result);
}
#pragma mark - 获取已注册的类的数量
- (void)btt_objc_getClassList {
//参数:1.传NUll获取当前注册的所有类 2.传0
//返回:所有注册类的总数
int result = objc_getClassList(NULL, 0);
NSLog(@"btt_objc_getClassList:%d",result);
}
#pragma mark - 设置对象的类
- (void)btt_object_setClass {
//参数:1.对象obj 2.类Class
//返回:类Class
Class result = object_setClass(self, [UIViewController class]);
NSLog(@"btt_object_setClass:%@",result);
}
#pragma mark - 获取对象的类对象
- (void)btt_object_getClass {
//参数:对象obj
//返回:类Class
Class result = object_getClass(self);
NSLog(@"btt_object_getClass:%@",result);
}
#pragma mark - 获取对象的类名
- (void)btt_object_getClassName {
//参数:对象obj
//返回:对象的类名
const char*result = object_getClassName(self);
NSLog(@"btt_object_getClassName:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 设置对象中实例变量的值
- (void)btt_object_setIvar {
Ivar ivar = class_getInstanceVariable(self.class, [@"_logic" UTF8String]);
//参数:1.对象obj 2.实例变量ivar 3.实例变量的值id
object_setIvar(self, ivar, @"123456");
}
#pragma mark - 获取对象中实例变量的值
- (void)btt_object_getIvar {
Ivar ivar = class_getInstanceVariable(self.class, [@"_logic" UTF8String]);
//参数:1.对象obj 2.实例变量ivar
//返回:id
NSString *result = object_getIvar(self, ivar);
NSLog(@"btt_object_getIvar:%@",result);
}
#pragma mark - 实例化类
- (void)btt_class_createInstance {
//参数:1.类Class 2.额外分配的字节数
//返回:类的实例
NSObject *result = class_createInstance([NSObject class], 0);
NSLog(@"btt_class_createInstance:%@",result);
}
#pragma mark - 注册使用类
- (void)btt_objc_registerClassPair {
Class result = objc_allocateClassPair([NSObject class], [@"NewClass" UTF8String], 0);
//参数:类Class
objc_registerClassPair(result);
}
#pragma mark - 销毁一个类
- (void)btt_objc_disposeClassPair {
//参数:类Class
Class result = objc_allocateClassPair([NSObject class], [@"NewClass" UTF8String], 0);
objc_disposeClassPair(result);
}
#pragma mark - 添加一个新类
- (void)btt_objc_allocateClassPair {
//参数:1.新添加类的父类 2.新类的名称 3.填0
//返回:新类
Class result = objc_allocateClassPair([NSObject class], [@"NewClass" UTF8String], 0);
NSLog(@"btt_objc_allocateClassPair:%p",result);
}
#pragma mark - 设置类的版本号
- (void)btt_class_setVersion {
//参数:1.类Class 2.int
class_setVersion(self.class, 100);
}
#pragma mark - 获取类的版本号
- (void)btt_class_getVersion {
//参数:类Class
//返回:版本号
int result = class_getVersion(self.class);
NSLog(@"btt_class_getVersion:%d",result);
}
#pragma mark - 获取协议列表
- (void)btt_class_copyProtocolList {
//入参:1、类Class 2、unsigned int 类型
//返回:整个类的遵循的协议
unsigned int copyProtocolListCount = 0;
Protocol * __unsafe_unretained *protocals = class_copyProtocolList([self class], ©ProtocolListCount);
for (NSInteger i = 0; i < copyProtocolListCount; i++) {
Protocol * protocal = protocals[i];
const char *name = protocol_getName(protocal);
NSLog(@"btt_class_copyProtocolList:%s",name);
}
free(protocals);//释放
}
#pragma mark - 判断是否遵循某个协议
- (void)btt_class_conformsToProtocol {
//参数:1.类Class 2.协议
//返回:BOOL
BOOL result = class_conformsToProtocol(self.class, NSProtocolFromString(@"UITableViewDelegate"));
NSLog(@"btt_class_conformsToProtocol:%d",result);
}
#pragma mark - 替换类的属性
- (void)btt_class_replaceProperty {
objc_property_attribute_t type = { "T", "@\"NSString\"" };
objc_property_attribute_t ownership = { "C", "" }; // C = copy
objc_property_attribute_t backingivar = { "V", "_attribute0" };
objc_property_attribute_t attrs[] = { type, ownership, backingivar };
//参数:1.类Class 2.属性名称 3.属性的相关属性 4.属性的相关属性的个数
class_replaceProperty(self.class, [@"logic" UTF8String], attrs, 3);
}
#pragma mark - 为类添加属性
//get方法
NSString *attribute0Getter(id classInstance, SEL _cmd) {
Ivar ivar = class_getInstanceVariable([classInstance class], "_attribute0");//获取变量,如果没获取到说明不存在
return object_getIvar(classInstance, ivar);
}
//set方法
void attribute0Setter(id classInstance, SEL _cmd, NSString *newName) {
Ivar ivar = class_getInstanceVariable([classInstance class], "_attribute0");//获取变量,如果没获取到说明不存在
id oldName = object_getIvar(classInstance, ivar);
if (oldName != newName) object_setIvar(classInstance, ivar, [newName copy]);
}
- (void)btt_class_addProperty {
objc_property_attribute_t type = { "T", "@\"NSString\"" };
objc_property_attribute_t ownership = { "C", "" }; // C = copy
objc_property_attribute_t backingivar = { "V", "_attribute0" };
objc_property_attribute_t attrs[] = { type, ownership, backingivar };
//参数:1.类Class 2.属性数组 3.属性个数
//返回值:BOOL
BOOL suc0 = class_addProperty(self.class, "_attribute0", attrs, 3);
SEL getter = NSSelectorFromString(@"attribute0");
SEL setter = NSSelectorFromString(@"setAttribute0:");
BOOL suc1 = class_addMethod(self.class, getter, (IMP)attribute0Getter, "@@:");
BOOL suc2 = class_addMethod(self.class, setter, (IMP)attribute0Setter, "v@:@");
NSLog(@"btt_class_addProperty:class_addProperty = %d,class_addMethod_Getter = %d,class_addMethod_Setter = %d",suc0,suc1,suc2);
}
#pragma mark - 添加协议
-(void)btt_class_addProtocol {
//参数:1.类Class 2.协议
//返回:BOOL
BOOL result = class_addProtocol([self class], NSProtocolFromString(@"UITableViewDelegate"));
NSLog(@"btt_class_addProtocol:%d",result);
}
#pragma mark - 判断是否响应方法
-(void)btt_class_respondsToSelector {
//参数:1.类Class 2.方法名SEL
//返回:BOOL
BOOL result = class_respondsToSelector(self.class, @selector(viewDidLoad));
NSLog(@"btt_class_respondsToSelector:%d",result);
}
#pragma mark - 获取方法实现
- (void)btt_class_getMethodImplementation {
//参数:1.类Class 2.方法名SEL
//返回:方法实现IMP
IMP result = class_getMethodImplementation([ViewController class], @selector(btt_method));
result();
}
- (void)btt_method {
NSLog(@"btt_method btt_method btt_method");
}
#pragma mark - 交换方法
- (void)btt_class_replaceMethod {
[self btt_method1];
//参数:1.类Class 2.方法名SEL 3.方法的实现IMP 4.方法参数描述
//返回:BOOL
BOOL result = class_replaceMethod([self class], @selector(btt_method1), [self methodForSelector:@selector(btt_method2)], NULL);
NSLog(@"btt_class_replaceMethod:%d",result);
[self btt_method1];
}
- (void)btt_method1 {
NSLog(@"btt_method1");
}
- (void)btt_method2 {
NSLog(@"btt_method2");
}
#pragma mark - 获取整个类的实例方法
- (void)btt_class_copyMethodList {
//参数:1、类Class 2、unsigned int 类型
//返回:整个类的实例方法
unsigned int copycopyMethodListCount = 0;
Method *methods = class_copyMethodList([self class], ©copyMethodListCount);
for (NSInteger i = 0; i < copycopyMethodListCount; i++) {
Method method = methods[i];
SEL name = method_getName(method);
NSLog(@"btt_class_copyMethodList:%@",NSStringFromSelector(name));
}
free(methods);//释放
}
#pragma mark - 获取类方法
- (void)btt_class_getClassMethod {
//入参:1.类Class 2.方法名SEL
//返回:method结构体指针
Method result = class_getClassMethod(self.class, @selector(bttClassMethod));
NSLog(@"btt_class_getClassMethod:%p",result);
}
+ (void)bttClassMethod {
NSLog(@"我是类方法");
}
#pragma mark - 获取类的实例方法
- (void)btt_class_getInstanceMethod {
//参数:1.类Class 2.方法名SEL
//返回:method结构体指针
Method result = class_getInstanceMethod(self.class, @selector(btt_method));
NSLog(@"btt_class_getInstanceMethod:%p",result);
}
#pragma mark - 给类添加方法
- (void)btt_addMethod {
//参数:1.类Class 2.方法名 3.imp,函数实现 4.方法参数类型描述
//返回值:BOOL
BOOL result = class_addMethod(self.class, NSSelectorFromString(@"lgMethod"), [self methodForSelector:@selector(btt_method)], "@@:");
NSLog(@"btt_addMethod:%d",result);
}
#pragma mark - 获取整个属性列表
- (void)btt_class_copyPropertyList {
//参数:1.类Class 2.unsigned int类型
//返回:属性列表
unsigned int copyPropertyListCount = 0;
objc_property_t *propertys = class_copyPropertyList([self class], ©PropertyListCount);
for (NSInteger i = 0; i < copyPropertyListCount; i++) {
objc_property_t property = propertys[i];
const char *name = property_getName(property);
NSLog(@"btt_class_copyPropertyList:%s",name);
}
free(propertys);//释放
}
#pragma mark - 获取指定的属性
- (void)btt_class_getProperty {
//参数:1.类Class 2.属性名
//返回:属性objc_property_t
objc_property_t result = class_getProperty(self.class, [@"logic" UTF8String]);
NSLog(@"btt_class_getProperty:%p",result);
}
#pragma mark - 获取类的weak修饰的实例变量
- (void)btt_class_getWeakIvarLayout {
//参数:类Class
//返回:返回值是指向 uint8_t 的指针
const uint8_t *result = class_getWeakIvarLayout(self.class);
NSLog(@"btt_class_getIvarLayout:%p",result);
}
#pragma mark - 设置类的实例变量的修饰符为weak
- (void)btt_class_setWeakIvarLayout{
uint8_t u = 1;
const uint8_t *u8 = &u;
//参数:1.类Class 2.const uint8_t *
class_setWeakIvarLayout(self.class, u8);
}
#pragma mark - 设置类的实例变量的修饰符
- (void)btt_class_setIvarLayout {
uint8_t u = 1;
const uint8_t *u8 = &u;
//参数:1.类Class 2.const uint8_t *
class_setIvarLayout(self.class, u8);
}
#pragma mark - 获取类的实例变量的修饰符
- (void)btt_class_getIvarLayout {
//参数:类Class
//返回:返回值是指向 uint8_t 的指针
const uint8_t *result = class_getIvarLayout(self.class);
NSLog(@"btt_class_getIvarLayout:%p",result);
}
#pragma mark - 获取整个成员变量列表
- (void)btt_class_copyIvarList {
//入参:1、类Class 2、unsigned int类型
//返回:Ivar 类型的指针数组
unsigned int copyIvarListCount = 0;
Ivar *ivars = class_copyIvarList([self class], ©IvarListCount);
for (NSInteger i = 0; i< copyIvarListCount; i ++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSLog(@"btt_class_copyIvarList:%s",name);
}
free(ivars);//释放
}
#pragma mark - 为动态创建的类添加变量
- (void)btt_class_addIvar {
Class CreatClass0 = objc_allocateClassPair([NSObject class], "CreatClass0", 0);
class_addIvar(CreatClass0, "_attribute0", sizeof(NSString *), log(sizeof(NSString *)), "i");
Ivar ivar = class_getInstanceVariable(CreatClass0, "_attribute0");//获取变量,如果没获取到说明不存在
NSLog(@"btt_class_addIvar:%@",[NSString stringWithUTF8String:ivar_getName(ivar)]);
objc_registerClassPair(CreatClass0);
}
#pragma mark - 获取指定的类变量的信息的数据结构的指针
- (void)btt_class_getClassVariable {
//参数:1.类Class 2.类变量名称
//返回:指定的类变量的信息的数据结构的指针
Ivar ivar = class_getClassVariable(self.class, [@"isa" UTF8String]);
NSLog(@"btt_class_getClassVariable:%p",ivar);
}
#pragma mark - 判断类是否为元类
- (void)btt_class_isMetaClass {
//参书:类Class
//返回:BOOL类型
BOOL result = class_isMetaClass([ViewController class]);
NSLog(@"btt_class_isMetaClass:%d",result);
}
#pragma mark - 获取父类
- (void)btt_class_getSuperclass {
//参数:类Class
//返回:父类Class
Class result = class_getSuperclass([ViewController class]);
NSLog(@"btt_class_getName:%@",result);
}
#pragma mark - 获取类名
- (void)btt_class_getName {
//参数:类Class
//返回:类名char数组
const char *result = class_getName([ViewController class]);
NSLog(@"btt_class_getName:%@",[NSString stringWithUTF8String:result]);
}
#pragma mark - 获取实例大小
- (void)btt_class_getInstanceSize {
//参数:类Class
//返回:类的实例大小
size_t result = class_getInstanceSize([ViewController class]);
NSLog(@"btt_class_getInstanceSize:%zu",result);
}
#pragma mark - 获取类中指定的实例变量的信息的数据结构的指针
- (void)btt_class_getInstanceVariable {
//参数:1.类Class 2.实例变量的名称
//返回:Ivar指针
const char *result1 = [@"_logic" UTF8String];
Ivar result2 = class_getInstanceVariable([self class], result1);
NSLog(@"btt_class_getInstanceVariable:%p",result2);
}
@end
未经作者授权,禁止转载
本文来自博客园,作者:CoderWGB,转载请注明原文链接:https://www.cnblogs.com/wgb1234/articles/16146405.html
THE END

浙公网安备 33010602011771号