Effective Objective-C 2.0 编写高质量iOS与OS X代码 理解“类对象”的用意

来源:互联网 发布:普象工业设计软件 编辑:程序博客网 时间:2024/04/29 07:57
问题:如果某类无法立即响应某个选择子,就会启动消息转发流程,然而,消息的接收者究竟是何物?是对象本身么?

1. 一般情况下应该指明消息接收者的具体类型,如果向其发送无法解读的消息,编译器会产生警告消息。
而类型id 的对象则不会,编译器假定它能响应所有的消息。

2. “在运行期检视对象类型”这一操作也叫做“类型信息查询”(inrtospection,“内省”),这个强大而有用的特性内置于Foundation框架的NSObject协议里。

3. 在程序中不要直接比较对象所属的类,明智的做法是调用“类型信息查询方法”。

4. 
typedef struct objc_object [
     Class isa;
} *id;

typedef struct objc_class *Class;
struct objc_class {
     Class isa;
     Class  super_class;
     const char *name;
     long version;
     long info;
     long instance_size;
     struct objc_ivar_list *ivars;
     struct objc_method_list **methodLists;
     struct objc_cache *cache;
     struct objc_protocol_list *protocols;
};

此结构体存放类的“元数据”(metadata)。
类对象所属的类型,即isa指针所指向的类型,叫做“元类”(metaclass)。
用来表述类对象本身所具备的元数据。


5. “isMemberOfClass:”能够判断出对象是否为某个特定类的实例。
“isKindOfClass:”能够判断对象是否为某类或其派生类的实例。

6. 比较类对象是否等同。一般用 == 操作符,而不用“isEqual:”。
因为类对象是“单例”,在应用程序范围内,每个类的class仅有一个实例。

但是最好还是使用类型信息查询方法。而不应该直接比较两个类对象是否等同。
因为牵着可以正确处理那些使用了消息传递机制的对象。比方说:
某个对象可能会把其收到的所有选择子都转发给另一个对象。
这样的对象叫做“代理”(proxy),此种对象均以NSProxy为根类。
通常情况下,在此种代理对象上调用class方法,那么返回的是代理对象本身。而非接受的代理的对象所属的类。
若是使用类型信息查询方法,那么代理对象就会把这条消息转给“接受代理的对象”。


摘取自:《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》,详细请购买书籍,支持作者及译者。
1 0
原创粉丝点击