给接受者发送消息,应该指明消息接受者的具体类型,这样向其发送无法解读的消息,编译器就会产生警告,而类型为id的对象则不然,编译器假定它能响应所有的消息。
NSString *string = @"some string";
上述代码,可以理解为存放NSString实例内存地址的变量指向NSString实例。
OC对象所用的数据结构定义在运行期程序库的头文件里。
// 对象结构体
struct objc_object {
Class isa;
};
typedef struct objc_object *id;
说明:
只有一个成员,Class类的变量,定义对象所属的类,通常称为“is a”指针
// Class对象
typedef struct objc_class *Class;
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY; // 元类
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父类
const char *name OBJC2_UNAVAILABLE; // 类名
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0
long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识
long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量链表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表
#endif
} OBJC2_UNAVAILABLE;
说明:
每个类仅有一个“类对象”,每个“类对象”仅有一个与之相关的“元类”。
super_class指针确立继承关系,isa指针描述实例所属的类。

在类继承体系中查询类型信息
在运行期检视对象类型,叫做“类型信息查询”。这一功能内置于NSObject协议里。由公共根类(NSObject和NSProxy)继承而来对象都要遵从次协议。
可以用类型信息查询检视继承体系。它使用isa指针获取对象所属的类,然后通过super_class指针在继承体系中游走。
“isMemberOfClass:”判断对象是否为某个特定类的实例。
“isKindOfClass:”判断对象是否为某类或其派生类的实例。
比较类对象是否等同可以用个==操作符,不能使用“isEqual:”。
原因:类对象是“单例”,在应用程序范围内,每个类的Class仅有一个实例。
// 判断类对象是否等同
if ([object class] == [EOCSomeClas class]) {
}
尽量使用类型信息查询方法来确定对象类型,而不要直接比较类对象,因为某些对象可能实现了消息转发功能。
原因:类型信息查询方法,正确处理那些使用了消息转发的对象,返回真实接受消息的对象。而使用class方法获取类对象,返回的类对象是消息转发中发起转发的对象,不是真实接受消息的对象。
网友评论