Objective-C 编程语言(10)选择器----"目标-动作"设计模式、避免发送消息时出错

转载请标明出处: http://blog.csdn.net/zhangxingping

目标-动作设计模式

    应用程序套件中的UI控件就很好地用到了上述的消息和接收者都可以动态变化的特性。

    NSControl类的对象都是可用于触发应用程序指令的图形设备。其中,大多数都类似于现实生活中的东西。比如按钮,开关,旋钮,文本框,拨号盘,菜单项等等。在软件中,这些设备是处在用户和应用程序之间的中间层。由它们负责把来自诸如键盘和鼠标的硬件事件转换为特定应用程序相关的指令。譬如:标有“查找”字样的按钮会把鼠标的点击事件转换为应用程序开始查找某个东西的指令。

    应用程序套件中定义了一些现成的这样的设备,并定义了用于创建这种控制设备的模版。例如:NSButtonCell类就定义了可以被赋值给NSMatrix实例作为其单元cell的对象。这个对象可以使用尺寸size,文本标签label,图片picture或者是键盘keyboar来进行初始化。当用户点击了这个按钮(或者使用了键盘),NSButtonCell对象就会发送消息,告知应用程序来做某件事情。此时,该NSButtonCell对象的初始化除了尺寸size,文本标签label之外还需要指明向谁发送什么消息。因此,NSButtonCell实例可以设定动作消息,也就是发送消息时使用的方法选择器,并设定目标,也就是接收该消息的对象。
[myButtonCell setAction:@selector(reapTheWind:)];
[myButtonCell setTarget:anObject];
    NSButtonCell对象使用NSObject类的performSelector:withObject:方法来发送消息。所有的动作消息都只需要一个参数,那就是发送该消息的控件的id。
如果Objectivec-C中,发送的消息是固定的,那么NSButtonCell对象将只能发送同一个消息;这个消息的名称将在NSButtonCell的实现代码中固化。这样buttonCell或者是其他的控件都将对消息的内容进行限制,而不是将用户的动作变换成具体的动作消息。这将倒置一个对象很难响应多个buttonCell。因为要么一个按钮只能有一个动作目标对象,要么这个目标对象需要对消息源于那个button进行甄别,然后做出不同的处理。当每次对用户界面进行重新布局的时候,我们将不得不重新实现响应这个消息的方法。这点正是Objective-C中所有避免的。

避免发送消息时出错

    在收到消息后,如果接收者没有要求的方法,此时就会出错。这种错误和调用一个不存在的函数是一样的。由于消息机制是在运行时进行的,因此这种错误只有在程序执行的时候才能被发现。

    在接收者类型已知,并且消息中的选择器是常量的时候,这种错误相对来说比较容易规避。在编写程序的时候,只需要确保接收者能够响应消息几个。如果接收者是静态类型的,编译器就能为我们完成这项工作。

     但是,如果接收者或者是消息中的选择器是可变的,那么这种检查就只能被延迟到运行时进行。在NSObject类中定义了方法respondsToSelector:来判断接收者时候可以响应某个消息。方法需要一个方法选择器作为其参数,返回接收者时候能够访问对应的方法:

if([anObject respondsToSelector:@selector(setOrigin::)])
     [anObjectsetOrigin:0.0 :0.0];
else
     fprint(stderr,”%scan't be placed\n”, [NSStringFromClass([anObject class])UTF8String]);
     当我们在向一个不能在编译时对其进行控制的对象发送消息的时候, respondsToSelector:方法提供的运行时检测就显得非常重要了。例如,当在代码中向一个用变量表示的对象发送消息的时候,而这个变量是别人不能修改的,那么我们就应该确保接收者确实实现了消息中对应的方法。


注意:消息的接收者如果不需要直接响应消息,是可以将消息转发给另外的对象的。此时,从调用者的角度来看(消息发送者的角度来看),消息的接收者是直接响应了该消息的。更多信息参阅《Objective-C运行时编程指南》中的“消息的转发”章节。



发布了22 篇原创文章 · 获赞 6 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/zhangxingping/article/details/7712632