美文网首页
iOS performSelector

iOS performSelector

作者: 青椒辣不辣 | 来源:发表于2020-12-14 15:23 被阅读0次

\color{rgb(0 ,139, 139)}{@protocol NSObject}

- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

两个参数以内

    // 0参数
    if ([self respondsToSelector:@selector(rj_selector)]) {//检测是否能响应方法
        [self performSelector:@selector(rj_selector)];//运行时调用方法
    }
    // 1参数
    if ([self respondsToSelector:@selector(rj_selector:)]) {
        [self performSelector:@selector(rj_selector:) withObject:@"小明"];
    }
    // 2参数
    if ([self respondsToSelector:@selector(rj_selector:age:)]) {
        [self performSelector:@selector(rj_selector:age:) withObject:@"小明" withObject:@19];
    }


-(void)rj_selector{
    NSLog(@"%s",__func__);
}
-(void)rj_selector:(NSString *)name{
    NSLog(@"%s",__func__);
    NSLog(@"-name---%@",name);
}
-(void)rj_selector:(NSString *)name age:(NSNumber *)age{
    NSLog(@"%s",__func__);
    NSLog(@"-name---%@",name);
    NSLog(@"-age---%d",age.intValue);
}

-[RJTextTwoViewController rj_selector]
-[RJTextTwoViewController rj_selector:]
-name---小明
-[RJTextTwoViewController rj_selector:age:]
-name---小明
-age---19

performSelector传递三个及以上的参数---NSInvocation

    if ([self respondsToSelector:@selector(rj_selector:age:height:)]) {
        NSArray *objs = [NSArray arrayWithObjects:@"小明", @19,@189.25,nil];
        [self performSelector:@selector(rj_selector:age:height:) withObjects:objs];
    }
-(void)rj_selector:(NSString *)name age:(NSNumber *)age height:(NSNumber *)height{
    NSLog(@"%s",__func__);
    NSLog(@"-name---%@",name);
    NSLog(@"-age---%d",age.intValue);
    NSLog(@"-age---%.2f",height.doubleValue);
}
- (id)performSelector:(SEL)selector withObjects:(NSArray *)objects{
    // 方法签名(方法的描述)
    NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
    if (signature == nil) {
        //可以抛出异常也可以不操作。
    }
    // NSInvocation : 利用一个NSInvocation对象包装一次方法调用(方法调用者、方法名、方法参数、方法返回值)
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = self;
    invocation.selector = selector;
    // 设置参数
    NSInteger paramsCount = signature.numberOfArguments - 2; // 除self、_cmd以外的参数个数
    paramsCount = MIN(paramsCount, objects.count);
    for (NSInteger i = 0; i < paramsCount; i++) {
        id object = objects[i];
        if ([object isKindOfClass:[NSNull class]]) continue;
        [invocation setArgument:&object atIndex:i + 2];
    }
    // 调用方法
    [invocation invoke];
    // 获取返回值
    id returnValue = nil;
    if (signature.methodReturnLength) { // 有返回值类型,才去获得返回值
        [invocation getReturnValue:&returnValue];
    }
    return returnValue;
}



-[RJTextTwoViewController rj_selector:age:height:]
-name---小明
-age---19
-age---189.25

传递三个及以上的参数---Runtime --> objc_msgSend
iOS Runtime 简单使用

    NSString *str = @"字符串objc_msgSend";
    NSNumber *num = @20;
    NSArray *arr = @[@"数组值1", @"数组值2"];
    SEL sel = NSSelectorFromString(@"ObjcMsgSendWithString:withNum:withArray:");
    ((void (*) (id, SEL, NSString *, NSNumber *, NSArray *)) objc_msgSend) (self, sel, str, num, arr);

- (void)ObjcMsgSendWithString:(NSString *)string withNum:(NSNumber *)number withArray:(NSArray *)array {
    NSLog(@"%@, %@, %@", string, number, array[1]);
}


-----------字符串objc_msgSend, 20, 数组值2

\color{rgb(0 ,139, 139)}{@interface NSObject (NSThreadPerformAdditions)}
iOS 多线程 pthread & NSthread

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
    // equivalent to the first method with kCFRunLoopCommonModes

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    // equivalent to the first method with kCFRunLoopCommonModes
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

\color{rgb(0 ,139, 139)}{@interface NSObject (NSDelayedPerforming)}

- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray<NSRunLoopMode> *)modes;
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;

\color{rgb(0 ,139, 139)}{@interface NSRunLoop (NSOrderedPerform)}

- (void)performSelector:(SEL)aSelector target:(id)target argument:(nullable id)arg order:(NSUInteger)order modes:(NSArray<NSRunLoopMode> *)modes;

相关文章

网友评论

      本文标题:iOS performSelector

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