首页 > 代码库 > Objective-C 浅谈

Objective-C 浅谈

Objective-C 与 C

  OC 在 C 的基础上添加了面向对象的特性,同时 OC 也是一种真正的动态语言。

  1.1 messaging structure 和 function calling

    C (function calling) : object->perform(param1, param2);

    OC (messaging structure) : [object performWith:param1 and:param2];

    在 messaging structure 中:

      object 被称为 “receiver”

      perform:and 被称为 “selector”

      “selector” 以及 param1 与 param2 合起来被称为 “message”。

  1.2 静态与动态

    C 是一种静态语言,所以函数调用(function calling)中调用的代码在编译的时候就已经被决定了。

    不过也有例外,C 有一种特性叫“动态绑定”,当调用的函数出现“多态”时,那么程序只有在运行的时候去定位需要执行的代码了。

      void func1();

      void func2();

      void test(bool flag)

      {

        void (*f)();

        if (flag) f = func1;

        else f = func2;

        f();

      }

    上面这个例子中,就应用到了“动态绑定”的特性。

    OC 是一种真正的动态语言(相较于java C++这些来说),其在运行时所执行的代码是由"OC runtime"决定的。当“receiver”接收到“message”之后,其究竟要调用哪个方法完全于运行期决定,有时甚至可以在运行时改变要执行的方法(比如“method swizzling”--常用于黑盒调试)。

    在编译器发现以 messaging structure 为原型的代码之后,会将其转换为标准的 function calling (通常以名为“objc_msgSend”的函数进行封装)。在程序运行期间,“objc_msgSend”会去寻找执行消息所需要的方法,寻找过程先后分为两步:查找“方法列表”和执行“消息转发”。

    由于动态语言在程序执行期间所遇到的复杂的查找过程,OC 设计了一种缓存机制,即为每一个类都分配一块缓存区,缓存区中保存之前匹配成功的“消息-方法”的映射。

    1.3 heap 和 stack

    C 通常将变量存储在栈区,而 OC 中所有的对象都必须被分配在堆上。

      Object *obj = [Object new];

      Object obj = [Object new];

    基于 OC 这样特殊的内存管理特性,在 OC 中声明一个对象都是以指针的形式进行,如果出现第二个情况就会报错“interface cannot be statically allocated”。

    尽管 OC 中的对象被存储在堆上,但是开发者并不需要执行复杂的内存管理工作。OC 提供了名为 ARC(Automic Reference Counting) 的内存管理机制。通过 ARC 开发者几乎可以把所有内存管理的工作都交给编译器。

 

property

    2.1 access method

    property 供了一种简洁的抽象机制来封装类的实例变量--access method。

    在 C++或者JAVA中,一个类的定义通常如下:

    class Object {

    public:

      int member1;

    private:

      int member2;

    }

    访问 member1 我们可以直接通过类的实例 object.member1 来访问;而访问 member2 我们只能通过在 Object 中添加 setter和geeter 来访问。

    access method 这一机制则可以自动生成实例变量的 getter 和 setter 方法。

    2.2 property 的属性特质

    property 声明的成员变量可以配置四中类型的特质:原子性、读写权限、内存管理、自定义 access method

      @property (nonatomic, readonly, copy, getter=isBFlag) BOOL bFlag;

    2.3 类内部访问 property

    默认的,OC 会在实例内部为每个 property 生成一个以 "_" 开头的变量,如 _bFlag。当然也可以通过 @synthesize 重新命名变量。

    在类内部应该尽可能的直接访问 property 变量,而不是使用 access method,这样做的好处好多:

      直接访问内存,加快存取速度

      绕过了"内存管理"的定义,不受其影响

      绕过了 KVO (key-value observing)的检测

 

protocol 与 category

  3.1 protocol

    protocol 类似 JAVA 中的 interface,其最常见的用途是实现"委托模式"。

    在 OC 中常见以 Delegate 结尾的定义,通过 Delegate 一个类可以要求被委托类实现一些必要的接口供着急调用。

  3.2 category

    category 是一种与 protocol 相比的反向操作,它能够向包含自己的类中添加新的方法。

    基于 category 的特性,可以将一个类的功能分散到多个分类中,以便于管理。

    @interface TransLayerProtocol : NSObject

      @property TCPProtocol tcpProto;

      @property UDPProtocol udpProto;

    - (void) goTcpProto;

    - (void) goUdpProto;      

    @end

    可以将 TransLayerProtocol 这个类(存于TransLayerProtocol.h/.m文件中)拆分为 TransLayerProtocol+TCP(TransLayerProtocol+TCP.h/.m)和TransLayerProtocol+UDP(TransLayerProtocol+UDP.h/.m)两个文件。

Objective-C 浅谈