OC&Swift runtime 一 object & Meth

2018-07-07  本文已影响0人  527267线的iOS工程师
image.png

define ISEQUAL(table, data1, data2) ((data1 == data2) || (*table->prototype->isEqual)(table->info, data1, data2))

(*table->prototype->isEqual)是方法名。table对象的prototype->isEqual。
(table->info, data1, data2)是上面这个方法的参数。
先判断指针。如果指针不相等 就不判断了。如果相等就接着走下去。活用||
方法一:object_copy
Discussion:ARC不能用
方法二: object_dispose
Discussion:ARC不能用
方法三: object_setInstanceVariable
Discussion:ARC不能用
方法四: object_getInstanceVariable
Discussion:ARC不能用
方法五: object_getIndexedIvars
Discussion:ARC不能用
方法六: object_setIvar
Discussion:如果实例变量的Ivar已知,那么object_setIvar要比object_setinstancevariar快。
OC

void object_setIvar(id obj, Ivar ivar, id value);
object_setIvar(self, class_getInstanceVariable([self class], "_property_1_s"), @"qqqqqqqqqqqqqqqqqqqqqqqqqqq");

方法七: object_getIvar
Discussion:如果实例变量的Ivar已知,那么object_getIvar要比object_getInstanceVariable快。
OC

id object_getIvar(id obj, Ivar ivar);
NSLog(@"set ivar%@", object_getIvar(self, class_getInstanceVariable([self class], "_property_1_s")));

方法八: object_getClassName
Discussion:
1、[NSArray new]类名叫_NSArray0
2、未init的arr3,类名叫做_NSPlaceHolderArray;
3、初始化后的可变数组类名都叫_NSArrayM;
4、初始化后的不可变数组类名都叫_NSArrayI.
instance返回的是class.class返回的是metaclass.metaclass返回的是NSObject。NSObject返回的是NSObject.
OC

const char * object_getClassName(id obj);
NSLog(@"%s", object_getClassName(@[@1,@2]));
NSLog(@"%s", object_getClassName([@[@1,@2] class]));
NSLog(@"%s", object_getClassName(object_getClass(object_getClass([@[@1,@2] class]))));

方法九: object_getClass
OC

Class object_getClass(id obj);
NSLog(@"%d", class_isMetaClass(object_getClass(@[@1,@2])));
NSLog(@"%d", class_isMetaClass(object_getClass([@[@1,@2] class])));

方法十: object_setClass
OC

Class object_setClass(id obj, Class cls);
Person * p1 = [[Person alloc] init];       
Class c1 = object_setClass(p1, [Dog class]);  
NSLog(@"c1 - %@", [c1 class]);  
NSLog(@"p1 - %@", [p1 class]); 

方法十一: objc_getClassList
OC

int objc_getClassList(Class  _Nonnull *buffer, int bufferCount);
int numClasses;
Class * classes = NULL;
classes = NULL;
numClasses = objc_getClassList(NULL, 0);
if (numClasses > 0 )
{
    classes = (Class *)malloc(sizeof(Class) * numClasses);
    numClasses = objc_getClassList(classes, numClasses);
    NSLog(@"%@", NSStringFromClass(*(classes + sizeof(Class) * 2)));
    free(classes);
}

方法十二: objc_copyClassList
OC

Class  _Nonnull * objc_copyClassList(unsigned int *outCount);
unsigned int classListCount;
Class *classList = objc_copyClassList(&classListCount);
int classListTmp = 0;
while (classListTmp < classListCount) {
    
    NSLog(@"%@", NSStringFromClass(*(classList + classListTmp)));
    classListTmp ++;
}

方法十三: objc_lookUpClass
Discussion:不同于objc_lookUpClass中,如果类没有注册,objc_getClass调用类的处理程序回调,然后检查第二次看有无类被注册。objc_lookUpClass不会调用类的处理程序回调。
OC

Class objc_lookUpClass(const char *name);
NSLog(@"%@", NSStringFromClass(objc_lookUpClass("DXArray")));

方法十四: objc_getClass
Discussion:objc_getClass不同于objc_lookUpClass,因为如果没有注册类,objc_getClass会调用类处理程序回调,然后再次检查类是否被注册。objc_lookUpClass不会调用类处理程序回调。
OC

id objc_getClass(const char *name);
NSLog(@"%@", NSStringFromClass(objc_getClass("DXArray")));

方法十五: objc_getRequiredClass
Discussion:此函数与objc_getClass相同,但是如果没有找到类,则会杀死进程。
这个函数是由ZeroLink使用的,如果找不到类,将是一个没有ZeroLink的编译时链接错误。
OC

Class objc_getRequiredClass(const char *name);
objc_getRequiredClass("DArray");

方法十六: objc_getMetaClass
Discussion:如果命名类的定义没有被注册,这个函数将调用类处理程序回调,然后再次检查类是否被注册。然而,每个类定义都必须有一个有效的元类定义,因此无论元类定义是否有效,都总是返回。
OC

id objc_getMetaClass(const char *name);
NSLog(@"%@", NSStringFromClass(objc_getMetaClass(class_getName([self class]))));

方法十七: ivar_getName
OC

const char * ivar_getName(Ivar v);
NSLog(@"666%s", ivar_getName(class_getInstanceVariable([self class], "_qqqqq")));

方法十八: ivar_getTypeEncoding

const char * ivar_getTypeEncoding(Ivar v);
Ivar *array = class_copyIvarList([self class], &i);
for (int temp = 0; temp < i; array++, temp++) {
    Ivar ivar = *array;
    NSLog(@"%s", ivar_getName(ivar));
    NSLog(@"%s", ivar_getTypeEncoding(ivar));
}

方法十九:ivar_getOffset
OC

ptrdiff_t ivar_getOffset(Ivar v);
printf("%td", ivar_getOffset(class_getInstanceVariable([self class], "_property_1_s")));

方法二十: objc_setAssociatedObject
OC

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
objc_setAssociatedObject(self, "imageRectName", rect, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

方法二十一: objc_getAssociatedObject
OC

id objc_getAssociatedObject(id object, const void *key);
objc_getAssociatedObject(self, "titleRectName");

方法二十二: objc_removeAssociatedObjects
Discussion:此函数的主要目的是使对象返回到“原始状态”变得容易。不应该将此函数用于从对象中删除关联,因为它还删除了其他客户机可能添加到对象中的关联。通常,应该使用objc_setAssociatedObject=nil值来清除关联。
OC

void objc_removeAssociatedObjects(id object);
objc_removeAssociatedObjects(self);

方法二十三: objc_msgSend
Discussion:void(IMP)(id, SEL) -> (void ()(id, SEL))objc_msgSend)
OC

id objc_msgSend(id self, SEL op, ...);
((int (*)(id, SEL))objc_msgSend)(self, @selector(nslogMySon));

方法二十四: objc_msgSend_fpret
Discussion:调用方法并且该方法返回float
OC

long double objc_msgSend_fpret(id self, SEL op, ...);
float f = ((float (*)(id, SEL))objc_msgSend_fpret)(self, @selector(fffff));

方法二十五: objc_msgSend_stret
Discussion:调用方法并且该方法返回struct
OC

void objc_msgSend_stret(id self, SEL op, ...);
CGRect d = ((CGRect (*)(id, SEL))objc_msgSend_stret)(self, @selector(rrrrr));

方法二十六: objc_msgSendSuper
Discussion:先看一下objc_super

struct objc_super {
    /// Specifies an instance of a class.
    __unsafe_unretained _Nonnull id receiver;

    /// Specifies the particular superclass of the instance to message. 
#if !defined(__cplusplus)  &&  !__OBJC2__
    /* For compatibility with old objc-runtime.h header */
    __unsafe_unretained _Nonnull Class class;
#else
    __unsafe_unretained _Nonnull Class super_class;
#endif
    /* super_class is the first class to search */
};

OC

id objc_msgSendSuper(struct objc_super *super, SEL op, ...);
struct objc_super superInfo = {
    self,
    [self superclass]
};
((void (*)(struct objc_super *, SEL))objc_msgSendSuper)(&superInfo, @selector(NSLOGQQQ));

方法二十七: objc_msgSendSuper_stret
Discussion:调用父类的方法并且该方法返回struct
OC

void objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...);
struct objc_super superInfo = {
    self,
    [self superclass]
};
((CGRect (*)(struct objc_super *, SEL))objc_msgSendSuper_stret)(&superInfo, @selector(rrrrr));

方法二十八: method_invoke
OC

id method_invoke(id receiver, Method m, ...);
((int (*)(id, Method))method_invoke)(self, class_getInstanceMethod([self class], @selector(nslogMySon)));

方法二十九: method_invoke_stret
OC

void method_invoke_stret(id receiver, Method m, ...);
((CGRect (*)(id, Method))method_invoke_stret)(self, class_getInstanceMethod([self class], @selector(rrrrr)));

方法三十: method_getName
OC

SEL method_getName(Method m);
method_getName(class_getClassMethod([NewModel class], @selector(load)));

方法三十一: method_getImplementation
OC

IMP method_getImplementation(Method m);
method_getImplementation(method2);

方法三十二: method_getTypeEncoding
OC

const char * method_getTypeEncoding(Method m);
NSLog(@"%s", method_getTypeEncoding(class_getInstanceMethod([self class], @selector(addMethodxxx:))));

方法三十三: method_copyReturnType
OC

char * method_copyReturnType(Method m);
NSLog(@"%s", method_copyReturnType(class_getInstanceMethod([self class], @selector(nslogMySon))));

方法三十四: method_copyArgumentType
OC
Discussion:返回的第一个是@第二个是:后面的才是我们写的方法参数

char * method_copyArgumentType(Method m, unsigned int index);
NSLog(@"%s", method_copyArgumentType(class_getInstanceMethod([self class], @selector(nslogMySon)), 0));

方法三十五: method_getReturnType
OC

void method_getReturnType(Method m, char *dst, size_t dst_len);
char returnType[255];
method_getReturnType(class_getInstanceMethod([self class], @selector(nslogMySon)),returnType , 255);

方法三十六: method_getNumberOfArguments
Discussion:最少为2.id + sel
OC

unsigned int method_getNumberOfArguments(Method m);
NSLog(@"%u", method_getNumberOfArguments(class_getInstanceMethod([self class], @selector(addMethodxxx:))));

方法三十七: method_getArgumentType
OC

void method_getArgumentType(Method m, unsigned int index, char *dst, size_t dst_len);
method_getArgumentType(class_getInstanceMethod([self class], @selector(nslogMySon)), 0, returnType, 1);

方法三十八: method_getDescription
OC

struct objc_method_description * method_getDescription(Method m);
struct objc_method_description * methodDescription = method_getDescription(class_getInstanceMethod([self class], @selector(addMethodxxx:)));

方法三十九: method_setImplementation
OC

IMP method_setImplementation(Method m, IMP imp);
method_setImplementation(class_getInstanceMethod([self class], @selector(rrrrr)), method_getImplementation(class_getInstanceMethod([self class], @selector(nslogMySon))));

方法四十: method_exchangeImplementations
OC

void method_exchangeImplementations(Method m1, Method m2);
Method method1 = class_getInstanceMethod(NSClassFromString(@"__NSArrayI"), @selector(objectAtIndex:));
Method method2 = class_getInstanceMethod([NSArray class], @selector(NewObjectAtIndex:));
method_exchangeImplementations(method1, method2);

if (class_replaceMethod(NSClassFromString(@"__NSArray0"), @selector(objectAtIndex:), method_getImplementation(method2), "")) {
    NSLog(@"1");
}else {
    NSLog(@"2");
}
上一篇 下一篇

猜你喜欢

热点阅读