官方文档介绍
- (id)performSelector:(SEL)aSelector;
Description
Sends a specified message to the receiver and returns the result of
the message. The performSelector: method is equivalent to sending an
aSelector message directly to the receiver. For example, the following
messages all do the same thing:
Listing 1
id aClone = [anObject copy];
id aClone = [anObject performSelector:@selector(copy)];
id aClone = [anObject performSelector:sel_getUid("copy")];
The performSelector: method allows you to send messages that aren’t
determined until run-time. This means that you can pass a variable
selector as the argument:
Listing 2
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
id returnedObject = [anObject performSelector:aSelector];
核心信息:
1、执行效果和发送消息等价
2、performSelector允许发送未在运行时确定的消息
测试
ViewController.h
@interface ViewController : UIViewController
@property (nonatomic, copy) NSString *birthday; // 支持
@property (nonatomic, weak) UIColor *color; // 支持
@property (nonatomic, assign) NSInteger age; // 不支持
-(NSInteger)test; // 支持
@end
ViewController.m
@interface ViewController ()
@property (nonatomic, copy) NSString *name;
- (void)test2;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.birthday = @"1212";
self.name = @"zw";
self.color = [UIColor redColor];
self.age = 121;
TestAViewController *testAVC = [TestAViewController new];
testAVC.vc = self;
[self.navigationController pushViewController:testAVC animated:YES];
}
- (NSInteger)test {
NSLog(@"dd");
return 11;
}
- (void)test2 {
NSLog(@"dd2");
}
@end
TestAViewController.m
// 对象是否实现了改方法
if ([_vc respondsToSelector:@selector(birthday)]) {
// performSelector获取的不能是基本数据类型变量, 方法不支持返回值,可以获取到对象中的私有属性值
id birthdayValue = [_vc performSelector:@selector(birthday)];
NSLog(@"%@",birthdayValue);
}
if ([_vc respondsToSelector:@selector(name)]) {
// performSelector获取的不能是基本数据类型变量, 方法不支持返回值,可以获取到对象中的私有属性值
id nameValue = [_vc performSelector:@selector(name)];
NSLog(@"%@",nameValue);
}
if ([_vc respondsToSelector:@selector(color)]) {
// performSelector获取的不能是基本数据类型变量, 方法不支持返回值,可以获取到对象中的私有属性值
id colorValue = [_vc performSelector:@selector(color)];
NSLog(@"%@",colorValue);
}
ViewController *vc = (ViewController*)_vc;
NSLog(@"%@",vc.birthday); // 效果和performSelector获取到到值一样
NSLog(@"%@",[vc test]); // 效果和performSelector一样
if ([vc respondsToSelector:@selector(test)]) {
// performSelector获取的不能是基本数据类型变量, 方法不支持返回值,可以获取到对象中的私有属性值
[vc performSelector:@selector(test)];
}
if ([vc respondsToSelector:@selector(test2)]) {
// performSelector获取的不能是基本数据类型变量, 方法不支持返回值,可以获取到对象中的私有属性值
[vc performSelector:@selector(test2)];
}
结论
- 对于公开属性和方法,通过对象使用performSelector和直接调用结果没有区别
- performSelector可以获取到及调用对象中的私有属性和方法
- performSelector获取变量时不能是基本数据类型的数据,copy、strong、weak修饰的都可以
- performSelector在调用方法时不支持返回值,否则会报错
- performSelector在编译过程中不存在对应方法不会报错,只有运行时才会报错,直接调用编译时就会报错, 为了避免运行报错,performSelector需要使用respondsToSelector检查方法或者属性是否存在