美文网首页
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让某对象执行特定多参数方法

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