博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Objective - C基础: 第四天 - 10.SEL类型的基本认识
阅读量:5049 次
发布时间:2019-06-12

本文共 2579 字,大约阅读时间需要 8 分钟。

在这之前, 我们回想一下, 我们知道实现我们所需要的功能, 就要调用某些方法, 那么这些方法又是怎么样调用的呢? 原理是怎么样的? 让我们一起来探讨一下看看~~

例子:

#import 
@interface Person : NSObject- (void)test;@end@implementation Person- (void)test{ NSLog(@"调用了test方法");}@endint main(){ Person *p = [[Person alloc]init]; [p test]; return 0;}
上面这个例子就是我们平常所写的, 那么方法调用的原理是什么??

1. 把test包装成SEL类型的数据.

2. 根据SEL数据找到对应方法的地址.

3. 根据方法地址调用对应的方法.

这就是方法调用的原理, 在我们所写的每一个方法中, 都会有相应的方法地址, 而SEL的任务就是去找对应方法的地址, 那么示意图是怎么样的呢? 让我们一起来看看:

那么根据这个, 我们就可以猜猜看, 在调用方法的时候是不是有多种方式呢, 继续往下看:

#import 
@interface Person : NSObject- (void)test2;@end@implementation Person- (void)test2{ NSLog(@"调用了test2方法.");}@endint main(){ Person *p = [[Person alloc]init]; [p test2]; [p performSelector:@selector(test2)]; return 0;}
结果:

2015-01-24 21:33:08.046 09-SEL类型[830:48415] 调用了test2方法.2015-01-24 21:33:08.047 09-SEL类型[830:48415] 调用了test2方法.

事实证明, 第二种方法也是可以的, 这种是属于间接调用, 那如果添加一个参数呢, 同样也是可以的.

#import 
@interface Person : NSObject+ (void)test;- (void)test2;- (void)test3:(NSString *)str;@end@implementation Person+ (void)test{ NSLog(@"调用了test方法.");}- (void)test2{ NSLog(@"调用了test2方法.");}- (void)test3:(NSString *)str{ NSLog(@"test3------%@", str);}@endint main() { Person *p = [[Person alloc]init]; [p test2]; [p performSelector:@selector(test2)]; [p performSelector:@selector(test3:) withObject:@"ABCDEFG"]; return 0;}
输出的结果:

2015-01-24 21:35:58.273 09-SEL类型[844:49833] 调用了test2方法.2015-01-24 21:35:58.274 09-SEL类型[844:49833] 调用了test2方法.2015-01-24 21:35:58.274 09-SEL类型[844:49833] test3------ABCDEFG

还有几种方法, 比如把字符串转成SEL类型:

int main() {    Person *p = [[Person alloc]init];            NSString *name = @"test2";    SEl s = NSSelectorFromString(name);    [p performSelector:s];    return 0;}
这样子也是可以调用的.

再补充一个知识点, 其实每一个方法内部都隐藏着一个SEL的数据, 而且是系统自带的, 叫做_cmd, 下面让我们来看看:

#import 
@interface Person : NSObject+ (void)test;- (void)test2;@end@implementation Person+ (void)test{ NSLog(@"调用了test方法.");}- (void)test2{ NSString *str = NSStringFromSelector(_cmd); NSLog(@"调用了test2方法------%@.", str);}@endint main() { Person *p = [[Person alloc]init]; [p test2]; return 0;}
结果:

2015-01-24 22:10:44.445 09-SEL类型[920:59424] 调用了test2方法---test2.
看到结果之后, 我们就知道了, 在哪个方法里调用_cmd, 那么这个_cmd就指向谁, 也就是代表着当前的这个方法.

注意, 千万不要在方法里面写一句这样子的代码:

[self performSelector:_cmd];
这样子会引发死循环的, 所以千万不能这么写.

总结一下: SEL其实是对方法的一种包装, 将方法包装成一个SEL类型的数据, 去找对应的方法地址, 找到该方法的地址, 就可以调用该方法了.

其实也可以这么说, SEL其实也是发送消息的一种, 原因就看上面的例子, 自己慢慢琢磨吧.

好了, 今天我们就讲到这里, 下次我们继续~~~

转载于:https://www.cnblogs.com/iOSCain/p/4282831.html

你可能感兴趣的文章
动态链接的步骤
查看>>
emacs 缩写词功能
查看>>
Api demo源码学习(2)--App/Activity/Custom Dialog --自定义Activity样式
查看>>
Velocity脚本简明教程
查看>>
虚拟机类加载机制
查看>>
RTSP流媒体数据传输的两种方式(TCP和UDP)
查看>>
大数n!
查看>>
LPC-LINK 2 LPC4370 简化线路图
查看>>
【模板】关于vector的lower_bound和upper_bound以及vector基本用法 STL
查看>>
linux c动态库编译好了,不能用。有些方法报(undefined reference)错误。
查看>>
在CentOS 6.5 中安装JDK 1.7 + Eclipse并配置opencv的java开发环境(二)
查看>>
docker 安装与卸载
查看>>
“搜狐微博零估值”用意何在
查看>>
如何区分 OpenStack Neutron Extension 和 Plugin
查看>>
简述人工智能发展的先决条件
查看>>
AWS API 2.0签名规范
查看>>
MVC3 系统列讲解
查看>>
很开心
查看>>
Codeforces 388 D. Fox and Perfect Sets
查看>>
货币计算程序
查看>>