NSObject深度解析

王飞虎
2023-12-01
一、NSObject类的理解:
Objective-C中有两个NSObject,一个是NSObject类,另一个是NSObject协议。而其中NSObject类采用了NSObject协议。在本文中,我们主要整理一下NSObject类的使用。
对于NSObject来说,我们可是非常熟悉的了,它是objc中大多数类的基类。注意,并不是所有的类都继承于NSObject,比如NSProxy类。
NSObject 点进去看代码是这样的
@interface NSObject < NSObject > {
    Class isa 
OBJC_ISA_AVAILABILITY ;
}

NSObject只有一个成员变量是Class类型的isa变量,那么class又是什么东西呢,再点进去看一下typedef struct objc_class *Class;Class是一个objc_class类型的结构体指针,那么这个结构体指针包含什么内容呢,于是我们在objc_class点进去(command+鼠标左键)
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
   
const char *name                                         OBJC2_UNAVAILABLE;
   
long version                                             OBJC2_UNAVAILABLE;
   
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
原来 objc_class是一个
struct objc_class {
    Class isa
 }这种东西

再将2个进行一下对比会发现长得好像啊
@interface NSObject < NSObject > {
    Class isa 
OBJC_ISA_AVAILABILITY ;
}

struct objc_class {
    Class isa
我们先捋一下
首先NSObject里面只有一个Class isa 的成员变量,而这个class就是一个objc_class的结构体指针,而这个objc_class结构体指针又包含了一个指向自身类型的指针变量isa。
我们都知道objc中id也是一种对象类型,那么它究竟是什么呢?看下面的定义
typedef struct objc_object {
    Class isa;
} *id;
原来id类型就是一个 objc_object 的一个结构体指针这个objc_object的结构体也仅仅包涵一个isa变量。
总结:我们可以得出这样的结论,在objc的runtime中,类是用 objc_class 结构体表示的,对象是用 objc_object 结构体表示的。 对象的 isa 用来表示这个对象是哪个类的实例。

二、NSObject协议方法:
- (BOOL)isEqual:(id)object;  比较两个对象的地址是否相等
- (id)performSelector:(SEL)aSelector;  调用Selector方法
- (id)performSelector:(SEL)aSelector withObject:(id)object; 调用sSelectopr方法,传一个参数
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; 调用sSelectopr方法,传两个参数
SEL就是对方法的一种包装。包装的SEL类型数据它对应相应的方法地址,找到方法地址就可以调用方法。在内存中每个类的方法都存储在类对象中,每个方法都有一个与之对应的SEL类型的数据,根据一个SEL数据就可以找到对应的方法地址,进而调用方法。
SEL类型的定义:  typedef struct objc_selector *SEL
SEL的使用:SEL S1 = @selector(test);    将test方法包装成SEL对象(无参)
SEL S2= @selector(test:);   将test方法包装成SEL对象(有参)
SEL S3 = NSSelectorFromString(@ "test");   将一个字符串方法转换成为SEL对象 
- (BOOL)isProxy; 判断一个实例是否继承自NSObject,如果返回NO就是继承自NSObject,反之返回YES
- (BOOL)isKindOfClass:(Class)aClass;  判断对象是否属于aClass及其子类
- (BOOL)isMemberOfClass:(Class)aClass;  判断对象是否属于aClass类
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;   检查某个对象是否遵守了aProtocol协议
- (BOOL)respondsToSelector:(SEL)aSelector;  判断对象是否能响应aSelector方法
 内存管理相关
- (instancetype)retain OBJC_ARC_UNAVAILABLE;
- (oneway void)release OBJC_ARC_UNAVAILABLE;
- (instancetype)autorelease OBJC_ARC_UNAVAILABLE;
- (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE;

二、NSObject方法和属性:
1.初始化相关
+ (void)load;  类的头文件被引入就会调用
+ (void)initialize;  类或其子类的第一个方法被调用之前调用
- (instancetype)init  初始化
+ (instancetype)new OBJC_SWIFT_UNAVAILABLE("use object initializers instead");  创建一个对象
+ (instancetype)allocWithZone:(struct _NSZone *)zone OBJC_SWIFT_UNAVAILABLE("use object initializers instead");  alloc方法内部调用该方法,返回分配的存储空间zone
+ (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead");  分配存储空间
- (void)dealloc OBJC_SWIFT_UNAVAILABLE("use 'deinit' to define a de-initializer");  对象销毁时调用
2.方法相关
+ (BOOL)instancesRespondToSelector:(SEL)aSelector;  判断类是否有aSelector方法
+ (BOOL)conformsToProtocol:(Protocol *)protocol;  判断类是否遵守此协议
- (IMP)methodForSelector:(SEL)aSelector;  根据一个SEL,得到该方法的IMP(函数指针)
+ (IMP)instanceMethodForSelector:(SEL)aSelector;  类方法,返回的是类方法的真正的函数地址
- (void)doesNotRecognizeSelector:(SEL)aSelector;  处理接收者无法识别的消息
- (id)forwardingTargetForSelector:(SEL)aSelector;  当某个对象不能接受某个selector时,将对该selector的调用转发给另一个对象
+ (BOOL)isSubclassOfClass:(Class)aClass;  判断一个类是否是其子类
+ (NSUInteger)hash; 如果isEqual判断两个对象相等,那么两个对象的hash返回值也一定相等。反之hsah值相等,isEqual未必认为两者一样。
+ (Class)superclass; 获得父类类对象
+ (Class)class OBJC_SWIFT_UNAVAILABLE("use 'aClass.self' instead"); 获得本类类对象
+ (NSString *)description;  NSLog打印格式。
+ (NSString *)debugDescription;  打断点时看到的格式。














 类似资料: