Monthly Archives: 02月 2011

Objective-C学习笔记1

因为工作需要,最近在学习Objective-C语言,越发觉得很有意思,感觉很是应该记录一下。

语言概况

简单来说,Objective-C是建立在ANSI C之上的语言。换言之,它与C++是平行而且对立的。在Objective-C中,面向对象概念的实现是从Smalltalk中借鉴而来的,与C++或Java的版本很不相同。它拥有如C++或Java一般的类继承结构,但同时又具备反射性(Reflection,能够在运行时修改对象行为的能力)。它同时支持强类型和弱类型,而且弱类型为真正的动态类型,这些变量在编译时并不会确定类型。某种意义上来说,Objective-C更像是C++与JavaScript的混合体:支持继承链、前期符号化+后期绑定、广义多态。

Objective-C兼顾性能与灵活性,看起来确实是种高级的语言。

消息机制

Objective-C中最有意思的概念就是传递消息了。在这个语言中,你不是“调用某个对象的某个方法”,而是“向某个对象发送一条消息”。简单地说,你是告诉某个对象,我要你执行一个名叫“doSomething”的方法,参数如下,什么什么的;至于接收方怎么处理这个消息,则是接收方的事情。接收方可以调用那个方法,也可以把这个消息转发给别的对象。

另外,消息是按名发送的,至于这个名字对应的是哪个方法,完全是运行时决定的。这体现出了Objective-C对象原生的多态性。消息的名字在Objective-C中叫做selector。selector类似于C++中的签名(signature),但selector中并不包含方法属主的信息,而且所有同名的方法都具有相同的selector。用C++的语言来解释就是,在不同类中的所有同名的方法都自动加入了同一个v-table中,无论它们之间是否有继承关系。这种按名调用的方式很接近于JavaScript等脚本语言,给程序开发提供了极大的灵活性。

self vs. this

Objective-C中的self指针更像是JavaScript中的this指针。它是动态的,指向消息接收的对象。我相信这个区别在设置callback时会体现出来,目前还没有很好的例子。

Protocol vs. Category

在Objective-C中,Protocol和Category都可以向已存在的类中安插更多的方法,而且它们都是静态的。

Protocol相当于C#和Java中的interface,或者C++中的抽象类。它定义了一系列的接口,而你需要对它们一一实现。一个Protocol可以被多个不同的类采用(adopt)。在定义一个接口时,无需提供该接口的实现。采用该接口的类负责实现这些接口。

Category则向已有的某个特定的类中直接增添新的方法。它可以将所有方法按照功能或者其它标准整理到不同的类别中。一个分类一定是扩展一个特定的类的,一旦扩展就会被视作原生方法,在运行时并无区别。在语义与语法上,Category很接近C#中的partial class,但Category还可以扩展源码不可用的类(例如NSObject等系统类)。

关于访问级别

由于Objective-C是靠消息传送机制来动态调用方法的,在运行时系统会自动寻找最匹配的方法来响应消息,所以这里并没有严格意义上的protected或者private方法。在这一点上,Objective-C很像JavaScript,用户需要用自己的方法来标识method的访问级别,而且无法真正意义上地隐藏某些method。

一个常见的方法是利用category。对所有方法进行分类,然后人工定义某些分类是“私有的”。另外,Objective-C 2.0支持空分类(也叫做extension),这个分类中的方法可以在主实现(main implementation)代码块中进行定义,这样就与私有方法的声明方式更加接近了。

这对一个从C++/Java刚刚转行过来的程序员来说可能会有些不适应,但实际上也提供了更多的灵活性。

关于Objective-C++

Objective-C++只是简单地将Objective-C和C++放在了同一个编译器中,使得在使用C++库时也能一同编译。Objective-C的部分和C++的部分完全独立运作,Objective-C对象和C++对象也互不兼容。

简单地说,使用Objective-C的对象时,向它们消息([obj doSomething]);使用C++对象时,调用其方法(obj->doSomething())。

这一个周末的学习就这么多收获,之后想到新的还会继续写。如果有不对的地方欢迎同学们指正!

加关注

Get every new post delivered to your Inbox.