obj-c中SEL签名和Invocation示例

时间:2021-11-12 20:37:13

参考小示例,代码如下:

#import <Foundation/Foundation.h>

@interface PlayList:NSObject
@property NSMutableArray *ary;
@end

@implementation PlayList

-(id)init{
    self = [super init];
    if(self){
        _ary = [NSMutableArray array];
    }
    return self;
}

-(NSMethodSignature *)methodSignatureForSelector:(SEL)selector{
    NSString *sel_name = NSStringFromSelector(selector);
    NSLog(@"%s:%@",__func__,sel_name);
    NSMethodSignature *sig = [_ary methodSignatureForSelector:selector];
    if(sig){
        //NSLog(@"%s:%@",__func__,sig);
        show_sig([sel_name UTF8String],sig);
        return sig;
    }
    return [super methodSignatureForSelector:selector];
}

-(void)forwardInvocation:(NSInvocation *)x{
    NSLog(@"%s:%@",__func__,x);
    [x invokeWithTarget:_ary];
}

void show_sig(const char* sig_name,NSMethodSignature *sig){
    const char *ret_type = [sig methodReturnType];
    NSUInteger arg_count = [sig numberOfArguments];
    NSLog(@"show sig for #%s# :",sig_name);
    NSLog(@"ret_type:%s , stack_len:%lu argc:%lu",ret_type,[sig frameLength],arg_count);

    for(int i = 0;i<arg_count;i++){
        printf("arg %d : %s ",i,[sig getArgumentTypeAtIndex:i]);
    }
    puts("");
}

-(NSUInteger)countOfAry{
    return [_ary count];
}

-(NSString *)description{
    NSLog(@"enter %s",__func__);
    return [NSString stringWithFormat:@"%@:%@",[self class],self.ary];
}
@end

int main(void){
    @autoreleasepool{
        PlayList *pl = [PlayList new];
        id ary_proxy = [pl mutableArrayValueForKey:@"ary"];
        NSLog(@"count is %ld(%ld)",[ary_proxy count],[pl countOfAry]);
        NSLog(@"%@",pl);

        id obj = pl;
        [obj addObject:@"hello"];
        [obj addObject:@"love"];
        //[obj love:@"panda" and:@"penguin"];
        NSLog(@"%@ has %lu",obj,[obj count]);
    }
    return 0;
}