惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
J
Java Code Geeks
罗磊的独立博客
雷峰网
雷峰网
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
爱范儿
爱范儿
B
Blog RSS Feed
腾讯CDC
Apple Machine Learning Research
Apple Machine Learning Research
D
Docker
Recent Announcements
Recent Announcements
T
Tailwind CSS Blog
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
小众软件
小众软件
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
I
InfoQ
S
SegmentFault 最新的问题

博客园 - 沙加

前端设计模式之 MPVC Part 3 前端设计模式之 MPVC Part 2 前端设计模式之 MPVC Part 1 App Engine 缓存与数据一致性 常用跨浏览器效果 同步请求真的有那么恐怖? Google Closure 的单元测试纪要 双飞翼布局的选区问题 一个 JS 面试题目 HTML 5 之旅 part 1 - 无头苍蝇 bind, delegate, live 三者的区别 Objective-C 学习笔记 - part 12 - 多线程 Objective-C 学习笔记 - part 11 - 错误处理 Objective-C 学习笔记 - part 9 - 静态标记的类型 Objective-C 学习笔记 - part 8 - 快速枚举 Objective-C 学习笔记 - part 7 - 相关引用 Objective-C 学习笔记 - part 6 - 类别与扩展 Objective-C 学习笔记 - part 5 - 申明属性 Objective-C 学习笔记 - part 4 - 协议
Objective-C 学习笔记 - part 10 - 选择器
沙加 · 2011-08-19 · via 博客园 - 沙加

在 object-c 中,selector 包含两种意义:在源文件中,它指向一个方法调用,在编译后它指向一个 unque indentifier。

编译后的 selector 的类型为 SEL,同名的方法的选择器也相同。

使用 selector 来调用object  方法是 Cocoa 框架  "目标-动作" 编程模型的基础。

可以使用 @selector 来为 selector 创建一个别名:

SEL setWidthHeight;
setWidthHeight = @selector(setWidth:height:);

在编译时用别名方法引用 seletor 不会对性能造成大的影响。如果是运行时需要根据一个字会串动态决态调用哪个方法可以下面的形式,有点类似于反射:
NSString *method;
method = NSStringFromSelector(setWidthHeight);

关于方法和选择器

框架只为 selector 分配 identifier 鸸 不是方法的实现,因此不同 class 的同名方法虽然 selector 的 identifier 一样,但是在执行是与方法调用无异。同时静态方法也可以与动态方法重名,因为他们有不同的归属对象。

动态类型标注时,同名方法必须是相同的参数类型与返回值,而静态类型标注时不需要。这是因为静态类型标注时可以通过类的元数据得知方法的实现。

除此之外,静态方法和实例方法也不受此限制,他们存在于不同的空间。

id   helper = getTheReceiver();
SEL  request = getTheSelector();
[helper performSelector:request];

如些的动态调用显得很强大。

[myButtonCell setAction:@selector(reapTheWind:)];
[myButtonCell setTarget:anObject];

上面的代码演示了如何将按钮和事件处理对象进行关联

虽然有一些手段使用动态 message 来维护按钮与事件处理对象的关系,但是苹果认为那会带来不必要的复杂性,因此使用了目前这种方式。

为了避免对象接受到它不能处理的消息,多用静态标注类型总是好的,因为它可以在编译时被检查。

如果一定要在运行时调用一个不能确定的方法,那么可以用这样的方式进行测试,以进行安全调用而不是报错:

if ( [anObject respondsToSelector:@selector(setOrigin::)] )
    [anObject setOrigin:0.0 :0.0];
else
    fprintf(stderr, "%s can’t be placed\n",
        [NSStringFromClass([anObject class]) UTF8String]);

另外,当对象不能处理一个消息时,它可以对它进行转发。详见 消息转发: http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtForwarding.html#//apple_ref/doc/uid/TP40008048-CH105