iOS开发 oc performSelector可否传参数,并举例说明

114 阅读2分钟

performSelector 方法在 Objective-C 中用于在运行时动态调用对象的方法。performSelector 可以传递参数,但其默认情况下最多只支持两个参数。如果需要传递更多参数,可以通过以下几种方式实现:

1. 使用 performSelector:withObject:withObject:...

performSelector:withObject:withObject:... 方法允许传递任意数量的参数,但需要注意的是,这种方法在实际使用中并不常见,且参数必须是对象类型。

示例:

[self performSelector:@selector(testMethod:param2:param3:) withObject:@"param1" withObject:@2 withObject:@3];

- (void)testMethod:(NSString *)param1 param2:(NSNumber *)param2 param3:(NSNumber *)param3 {

NSLog(@"param1: %@, param2: %@, param3: %@", param1, param2, param3);

}

2. 使用 objc_msgSend

objc_msgSend 是 Objective-C 消息机制的核心函数,可以传递任意数量的参数,包括非对象类型的参数。通过 objc_msgSend 可以实现多参数传递。

示例:

#import <objc/message.h>

- (void)viewDidLoad {

[super viewDidLoad];

NSString *param1 = @"111";

NSArray *param2 = @[@2, @3];

NSInteger param3 = 123;

((void (*)(id, SEL, NSString *, NSArray *, NSInteger))objc_msgSend)(self, @selector(testMethod:param2:param3:), param1, param2, param3);

}

- (void)testMethod:(NSString *)param1 param2:(NSArray *)param2 param3:(NSInteger)param3 {

NSLog(@"param1: %@, param2: %@, param3: %ld", param1, param2, (long)param3);

}

3. 使用 NSInvocation

NSInvocation 是一种更灵活的方式,可以用来封装方法调用,包括方法签名、目标对象、选择器和参数。这种方式适用于需要传递多个参数的情况。

示例:

#import <Foundation/Foundation.h>

- (void)viewDidLoad {

[super viewDidLoad];

SEL selector = @selector(testMethod:param2:param3:);

NSMethodSignature *signature = [self methodSignatureForSelector:selector];

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

invocation.target = self;

invocation.selector = selector;

NSString *param1 = @"111";

NSArray *param2 = @[@2, @3];

NSInteger param3 = 123;

[invocation setArgument:&param1 atIndex:2];

[invocation setArgument:&param2 atIndex:3];

[invocation setArgument:&param3 atIndex:4];

[invocation invoke];

}

- (void)testMethod:(NSString *)param1 param2:(NSArray *)param2 param3:(NSInteger)param3 {

NSLog(@"param1: %@, param2: %@, param3: %ld", param1, param2, (long)param3);

}

4. 封装参数

将多个参数封装成一个对象(如 NSDictionary 或 NSArray),然后通过 performSelector:withObject: 传递。

示例:

- (void)viewDidLoad {

[super viewDidLoad];

NSDictionary *params = @{@"param1": @"111", @"param2": @[@2, @3], @"param3": @123};

[self performSelector:@selector(testMethodWithParams:) withObject:params];

}

- (void)testMethodWithParams:(NSDictionary *)params {

NSString *param1 = params[@"param1"];

NSArray *param2 = params[@"param2"];

NSInteger param3 = [params[@"param3"] integerValue];

NSLog(@"param1: %@, param2: %@, param3: %ld", param1, param2, (long)param3);

}

总结

performSelector 本身默认只支持传递两个参数,但通过上述方法,可以实现传递多个参数的需求。选择哪种方法取决于具体的应用场景和代码的可读性要求。