为什么要用 SEL
主要是 API 要求的,其它情况另定
Summary
可以理解 @selector() 就是取类方法的编号,
它的行为基本可以等同 C语言 中的函数指针,
只不过 C 语言 中,可以把函数名直接赋给一个函数指针,
而 Object-C 的类不能直接应用函数指针,
这样只能做一个 @selector 语法来取.
每个 SEL 类型数据都是一个方法。
SEL 就是对方法的一种包装。
包装的 SEL 类型数据它对应相应的方法地址,
找到方法地址就可以调用方法。
在内存中每个类的方法都存储在类对象中,
每个方法都有一个与之对应的 SEL 类型的数据,
根据一个 SEL 数据就可以找到对应的方法地址,
进而调用方法。
Demo
#import "ViewController.h"
#define SuppressPerformSelectorLeakWarning(Stuff) \
do { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
Stuff; \
_Pragma("clang diagnostic pop") \
} while (0)
@interface ViewController ()
@end
@interface Person : NSObject
- (void)test;
- (void)test:(NSString *)string;
@end
@implementation Person
- (void)test {
NSLog(@"___test___");
}
- (void)test:(NSString *)string {
NSLog(@"___test___%@", string);
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
Person *p = [Person new];
// 手动把 test 方法包装成 SEL 类型
SEL s1 = @selector(test);
SEL s2 = @selector(test:);
// 响应方法
SuppressPerformSelectorLeakWarning([p performSelector:s1]);
SuppressPerformSelectorLeakWarning([p performSelector:s2 withObject:@"参数"]);
SEL selector1 = NSSelectorFromString(@"test");
((void (*)(id, SEL))[p methodForSelector:selector1])(p, selector1);
}
@end
我的理解
Person *p = [Person new];
// 第一步,就是用 SEL 定义一个对象,这个对象用 @selector 的方式拥有了 p 的(test)方法
SEL s1 = @selector(test);
// 第二步,执行这个 s1 对象,就是执行这个方法
[p performSelector:s1]
【原创:iOS第九层】
网友评论