美文网首页
第14条:理解“类对象”的用意

第14条:理解“类对象”的用意

作者: MrSYLong | 来源:发表于2018-08-19 17:07 被阅读10次

给接受者发送消息,应该指明消息接受者的具体类型,这样向其发送无法解读的消息,编译器就会产生警告,而类型为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指针描述实例所属的类。
继承体系.jpg

在类继承体系中查询类型信息

在运行期检视对象类型,叫做“类型信息查询”。这一功能内置于NSObject协议里。由公共根类(NSObject和NSProxy)继承而来对象都要遵从次协议。

可以用类型信息查询检视继承体系。它使用isa指针获取对象所属的类,然后通过super_class指针在继承体系中游走。

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

比较类对象是否等同可以用个==操作符,不能使用“isEqual:”。
原因:类对象是“单例”,在应用程序范围内,每个类的Class仅有一个实例。

// 判断类对象是否等同
if ([object class] == [EOCSomeClas class]) {
    
}

尽量使用类型信息查询方法来确定对象类型,而不要直接比较类对象,因为某些对象可能实现了消息转发功能。
原因:类型信息查询方法,正确处理那些使用了消息转发的对象,返回真实接受消息的对象。而使用class方法获取类对象,返回的类对象是消息转发中发起转发的对象,不是真实接受消息的对象。

相关文章

网友评论

      本文标题:第14条:理解“类对象”的用意

      本文链接:https://www.haomeiwen.com/subject/magciftx.html