美文网首页
OC&Swift runtime 一 object & Meth

OC&Swift runtime 一 object & Meth

作者: 527267线的iOS工程师 | 来源:发表于2018-07-07 10:26 被阅读0次
    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");
    }
    

    相关文章

      网友评论

          本文标题:OC&Swift runtime 一 object & Meth

          本文链接:https://www.haomeiwen.com/subject/bblaeftx.html