?
Objective-C最大的特色是承自Smalltalk的信息传递模型(message passing),此机制与今日C++式之主流风格差异甚大。Objective-C里,与其说对象互相调用方法,不如说对象之间互相传递信息更为精确。此二种风格的主要差异在于调用方法/信息传递这个动作。C++里类型与方法的关系严格清楚,一个方法必定属于一个类型,而且在编译时(compile time)就已经紧密绑定,不可能调用一个不存在类型里的方法。但在Objective-C,类型与信息的关系比较松散,调用方法视为对对象发送信息,所有方法都被视为对信息的回应。所有信息处理直到运行时(runtime)才会动态决定,并交由类型自行决定如何处理收到的信息。也就是说,一个类型不保证一定会回应收到的信息,如果类型收到了一个无法处理的信息,程序只会抛出异常,不会出错或崩溃。
C++里,送一个信息给对象(或者说调用一个方法)的语法如下:
obj->method(argument);
Objective-C则写成:
[obj method: argument];
此二者并不仅仅是语法上的差异,还有基本行为上的不同。
这里以一个汽车类(car class)的简单例子来解释Objective-C的信息传递特性:
[car fly];
典型的C++意义解读是“调用car类型的fly方法”。若car类型里头没有定义fly方法,那编译肯定不会通过。但是Objective-C里,我们应当解读为“发提交一个fly的信息给car对象”,fly是信息,而car是信息的接收者。car收到信息后会决定如何回应这个信息,若car类型内定义有fly方法就运行方法内之代码,若car内不存在fly方法,则程序依旧可以通过编译,运行期则抛出异常。
此二种风格各有优劣。C++强制要求所有的方法都必须有对应的动作,且编译期绑定使得函数调用非常快速。缺点是仅能借由virtual关键字提供有限的动态绑定能力。Objective-C天生即具备鸭子类型之动态绑定能力,因为运行期才处理信息,允许发送未知信息给对象。可以送信息给整个对象集合而不需要一一检查每个对象的型态,也具备消息转送机制。同时空对象nil接受信息后默认为不做事,所以送信息给nil也不用担心程序崩溃。
Objective-C的方法调用因为运行期才动态解析信息,一开始信息比C++ virtual成员函数调用速度慢上三倍。但经由IMP高速缓存改善,目前已经比C++的virtual function快上50%[1]。
创建新对象?
为了创建新对象,我们需要向相应的类发送new消息。 该类接收并处理完new消息后,我们就会得到一个可以使用的新对象实例了。 例如: id Shape[3]; Shape[0] = [Circle new]; //向Circle类发送new消息,则创建了新对象,并把该新对象赋给Shape[0].
?在类中向超类发送消息
3.1 例如: @interface Circle : Shape @end // Circle @implementation Circle -(void) SetFillColor:(ShapeColor) c { if (c == kRedColor) { c = kGreenColor; } [super setFillColor:c]; // 向超类Shape发送消息,超类将会执行它的setFillColor方法。 } @end //Circle 3.2 例如: self = [super init]; //作用是,使超类NSObject完成它的初始化工作。并且如果返回一个新对象, //则需要更新self。
用于通知某个对象该做什么即通知对象去执行某动作
?在Objective-C中,方括号还有其它意义:它们用于通知某个对象该做什么。 例如: [shape draw]; //这句话说明,通知对象shape去执行draw这个动作,例如让一个rectangle去画一个矩形。 ?
|