iOS笔记-performSelector的探索

本文探讨了iOS中performSelector的使用,包括其官方文档的描述,它如何允许在运行时发送未确定的消息。核心信息表明,performSelector可用于调用私有属性和方法,并且在调用时需要注意返回值问题和数据类型限制。测试结果证明,对于公开属性和方法,performSelector与直接调用等效,但在编译时期不检查方法存在性,运行时才进行检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官方文档介绍

- (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)];
    }

结论

  1. 对于公开属性和方法,通过对象使用performSelector和直接调用结果没有区别
  2. performSelector可以获取到及调用对象中的私有属性和方法
  3. performSelector获取变量时不能是基本数据类型的数据,copy、strong、weak修饰的都可以
  4. performSelector在调用方法时不支持返回值,否则会报错
  5. performSelector在编译过程中不存在对应方法不会报错,只有运行时才会报错,直接调用编译时就会报错, 为了避免运行报错,performSelector需要使用respondsToSelector检查方法或者属性是否存在
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值