1. 程式人生 > 其它 >複習總結 Runtime

複習總結 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], &copyProtocolListCount); 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], &copycopyMethodListCount); 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], &copyPropertyListCount); 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], &copyIvarListCount); 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