美文网首页
runtime让某对象执行特定多参数方法

runtime让某对象执行特定多参数方法

作者: Dawn_wdf | 来源:发表于2017-07-26 15:14 被阅读20次
+ (id)dw_target:(id)target performSel:(SEL)sel arguments:(id)firstObj,... NS_REQUIRES_NIL_TERMINATION {
    //获取信号量
    NSMethodSignature *signature = [target methodSignatureForSelector:sel];
    
    NSAssert(signature, @"method : %@ does not implementation",NSStringFromSelector(sel));
    
    NSInteger numberOfArguments = signature.numberOfArguments;
    
    //配置invocation并执行 获取返回参数
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.selector = sel;
    invocation.target = target;
    
    //获取可变参数
    va_list list;
    va_start(list, firstObj);
    int i = 0;
    for (id temp = firstObj;temp != nil;temp = va_arg(list, id)){
        if (i >= numberOfArguments - 2){
            break;
        }
        [invocation setArgument:&temp atIndex:i + 2];
        i++;
    }
    [invocation retainArguments];
    va_end(list);
    
    if ([invocation.target respondsToSelector:invocation.selector]) {
        [invocation invokeWithTarget:invocation.target];
    }else{
        return nil;
    }
    
    const char *returnType = signature.methodReturnType;

    id  returnValue;

    if( !strcmp(returnType, @encode(void)) ){
        returnValue =  nil;
    }else if( !strcmp(returnType, @encode(id)) ){
        [invocation getReturnValue:&returnValue];
    }else{
        NSUInteger length = [signature methodReturnLength];
        
        void *buffer = (void *)malloc(length);
        [invocation getReturnValue:buffer];
        
        if (strcmp(returnType, @encode(char)) == 0) {
            returnValue = [NSNumber numberWithChar:*((char*)buffer)];
        } else if (strcmp(returnType, @encode(int)) == 0) {
            returnValue = [NSNumber numberWithInt:*((int *)buffer)];
        } else if (strcmp(returnType, @encode(short)) == 0) {
            returnValue = [NSNumber numberWithShort:*((short *)buffer)];
        } else if (strcmp(returnType, @encode(long)) == 0) {
            returnValue = [NSNumber numberWithLong:*((long *)buffer)];
        } else if (strcmp(returnType, @encode(long long)) == 0) {
            returnValue = [NSNumber numberWithLongLong:*((long long *)buffer)];
        } else if (strcmp(returnType, @encode(unsigned char)) == 0) {
            returnValue = [NSNumber numberWithUnsignedChar:*((unsigned char *)buffer)];
        } else if (strcmp(returnType, @encode(unsigned int)) == 0) {
            returnValue = [NSNumber numberWithUnsignedInt:*((unsigned int *)buffer)];
        } else if (strcmp(returnType, @encode(unsigned short)) == 0) {
            returnValue = [NSNumber numberWithUnsignedShort:*((unsigned short *)buffer)];
        } else if (strcmp(returnType, @encode(unsigned long)) == 0) {
            returnValue = [NSNumber numberWithUnsignedLong:*((unsigned long *)buffer)];
        } else if (strcmp(returnType, @encode(unsigned long long)) == 0) {
            returnValue = [NSNumber numberWithUnsignedLongLong:*((unsigned long long *)buffer)];
        } else if (strcmp(returnType, @encode(float)) == 0) {
            returnValue = [NSNumber numberWithFloat:*((float *)buffer)];
        } else if (strcmp(returnType, @encode(double)) == 0) {
            returnValue = [NSNumber numberWithDouble:*((double *)buffer)];
        } else if (strcmp(returnType, @encode(BOOL)) == 0) {
            returnValue = [NSNumber numberWithBool:*((BOOL *)buffer)];
        } else {
            returnValue = [NSValue valueWithBytes:buffer objCType:returnType];
        }

    }
    return returnValue;

}

使用方法:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    
    NSValue *value = [NSObject dw_target:self.originalDelegate performSel:_cmd arguments:collectionView,collectionViewLayout, nil];
    UIEdgeInsets insets = UIEdgeInsetsZero;
    [value getValue:&insets];
    return insets;
}




- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    
    NSNumber *value = [NSObject dw_target:self.originalDelegate performSel:_cmd arguments:collectionView,collectionViewLayout,@(section), nil];

    if (!value) {
        return CGFLOAT_MIN;
    }
    return [value floatValue];
}

相关文章

  • runtime让某对象执行特定多参数方法

    使用方法:

  • iOS面试题-Runtime

    Runtime 一、消息机制:对象根据方法编号SEL去映射表查找对应的方法实现。 objc_msgSend参数概念...

  • JAVA生成随机数

    生成特定区间随机数 使用Random类 Random 对象的 nextInt(int) 方法,将生成 0 ~ 参数...

  • Runtime-原理

    runtime初探对象与方法的本质runtime-消息发送runtime-动态方法解析runtime-消息转发 r...

  • 2020-02-23 Runtime

    目录: 01-Runtime 初探 02-Runtime 对象与方法的本质 03-Runtime 动态方法解析 0...

  • NSObject的load和initialize方法

    load方法: 在类对象一被加载到进程的地址空间内,runtime就会向每个类对象发送load消息。对于程序可执行...

  • 函数参数

    默认参数值 ES2015语法直接实现默认参数值: 默认参数特性还可以用在对象的方法中,而且默认值还是可以是对象的某...

  • 2.2 对象和方法之间的关系

    本小节知识点: 【掌握】对象作为方法的参数 【掌握】对象作为方法的返回值 1.对象作为方法的参数 对象作为方法参数...

  • IOS delegate 命名规范

    方法命名 当特定的事件发生时, 对象会触发它注册的委托方法. 委托的方法, 第一个参数是触发它的对象,第一个关键词...

  • iOS-NSTimer()

    NSTimer 每隔一定时间执行某个函数 //创建定时器//参数1.定时时间//参数2.调用方法的对象//参数3....

网友评论

      本文标题:runtime让某对象执行特定多参数方法

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