Effective Objective-C 2.0 — 第14条:理解“类对象“的用意

时间:2021-10-16 11:24:54
  • 每个实例都有一个指向Class 对象的指针,用以表明其类型,而这些 Class 对象则构成了类的继承体系。
  • 如果对象类型无法在编译期确定,那么就应该使用类型信息查询方法来探知。
  • 尽量使用类型信息查询方法来确定对象类型,而不要直接比较类对象,因为某些对象可能实现了消息转发功能。

类型 id 能指代任意的Objective-C 对象类型,编译器假定 类型为 id 的对象 能响应所有消息

Objective-C 对象的本质

每个 Objective-C 对象实例都是指向某块内存数据的指针。,所以在声明变量时,类型后面要跟一个”*“字符

NSString *pointerVariable = @"Some string";

id 本身已经是 指针了

id genericTypedString = @"Some string";
描述Objective-C 对象所用的数据结构定义在运行期程序库的头文件里,
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)。
用来表述类对象本身所具备的元数据。
Effective Objective-C 2.0 — 第14条:理解“类对象“的用意
“isMemberOfClass:”能够判断出对象是否为某个特定类的实例。
“isKindOfClass:”能够判断对象是否为某类或其派生类的实例。
比较类对象是否等同。一般用 == 操作符,而不用“isEqual:”。
因为类对象是“单例”,在应用程序范围内,每个类的class仅有一个实例。
但是最好还是使用类型信息查询方法。而不应该直接比较两个类对象是否等同。
因为牵着可以正确处理那些使用了消息传递机制的对象。比方说:
某个对象可能会把其收到的所有选择子都转发给另一个对象。
这样的对象叫做“代理”(proxy),此种对象均以NSProxy为根类。
通常情况下,在此种代理对象上调用class方法,那么返回的是代理对象本身。而非接受的代理的对象所属的类。
若是使用类型信息查询方法,那么代理对象就会把这条消息转给“接受代理的对象”。