问题:如果某类无法立即响应某个选择子,就会启动消息转发流程,然而,消息的接收者究竟是何物?是对象本身么?
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代码 理解“类对象”的用意,,5-wow.com