复习总结 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
签 名:被别人嫉妒,说明你卓越;你嫉妒别人,说明你无能。
座右铭:抓紧一切时间睡觉。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)