源码

【API使用系列,整理】NSObject专题

1 NSObject源码实现分析

Objective-C NSObject的实现分析(2014-10-23更新)

http://blog.csdn.net/uxyheaven/article/details/38120335

1.1 属性

1.1.1 isa

是一个指向Class的指针,具体请看这篇文章Objective-C objc_class介绍

1.2 方法

1.2.1 class

实例方法返回的是isa指针, 类方法返回的是本身

代码实现如下:

class 

    return (id)isa;  

class  

    return self; 
}

1.2.2 superclass

返回父类

代码实现如下:

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

调用的是runtime中的class_getSuperclass方法,跟踪到最后实例方法返回的是isa->superclass,类方法返回的是self->superclass

static class_t * getSuperclass(class_t *cls) 

    if (!cls) return NULL
    return cls->superclass; 

1.2.3 isEqual

就是直接比较

- (BOOL)isEqual:anObject 

    return anObject ==self;  

- (BOOL)isEqual:anObject
{
    return anObject == self;
}

1.2.4 isMemberOf:

- (BOOL)isMemberOf:aClass
{
    return isa == (Class)aClass;
}

看代码可以得知是通过比较实例对象的isa是否和 传过来的[类 Class] 一样来判断的.而实例对象的isa确实就是指着实例对象的类的.

- (BOOL)isMemberOf:aClass 

    return isa ==(Class)aClass; 
}

1.2.5 isKindOf:

- (BOOL)isKindOf:aClass
{
    register Class cls;
    for (cls = isa; cls; cls = class_getSuperclass(cls))
        if (cls == (Class)aClass)
            return YES;
    return NO;
}
// class_getSuperclass展开后如下
static class_t *getSuperclass(class_t *cls)
{
   if (!cls) return NULL;
    return cls->superclass;
}

代码思路也很好理解,如果自己的isa等于aClass(aClass的父类,此处循环)就返回YES,否则返回NO

- (BOOL)isKindOf:aClass 

    register Classcls; 
    for (cls = isa;cls; cls = class_getSuperclass(cls))  
        if (cls ==(Class)aClass) 
            returnYES; 
    return NO; 

// class_getSuperclass展开后如下  
static class_t * getSuperclass(class_t *cls) 

    if (!cls) returnNULL; 
    return cls->superclass; 

1.2.6 init

- init
{
    return self;
}

没什么好说的

- init 

    return self

1.2.7 alloc

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

0

这里有一个函数指针和一个结构体,我们跟进去看

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

1

上面那段代码的作用是:

    1、得到这个类占用多少空间,最小占16 bytes;

    2、然后就给这个实例分配多少空间, 如果失败的话就返回nil;

    3、把这个实例的isa设置成这个类对象;

    4、如果cls的info设置了get属性就用cls这个类在obj这个空间去构造一个实例,跟进去是

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

2

大意是,先看自己有没有父类,有就递归调用自己,然后给自己添加方法,然后添加类别

1.2.8 new

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

3

跟进去看一下,发现是和alloc差不多

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

4

1.2.9 free

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

5

跟进去看一下

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

6

    1、执行一个叫object_cxxDestruct的东西干了点什么事(沿着继承链逐层向上搜寻SEL_cxx_destruct这个selector,找到函数实现(void (*)(id)(函数指针)并执行);

    2、 执行_object_remove_assocations去除和这个对象关联的对象;

    3、执行objc_clear_deallocating,清空引用计数表并清除弱引用表,将所有weak引用指nil

1.2.10 respondsTo:

是查找有没有实现某个方法

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

7

1.2.11 perform:

perform是发送消息到指定的接收器并返回值,下面是代码:

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

8

原来就是objc_msgSend这玩意.objc_msgSend实现有很多个版本,大体逻辑应该差不多,首先在找缓存,找到就跳转过去,找不到就在Class的方法列表里找方法,如果还是没找到就转发.

下的是arm下的代码

+ superclass  
{  
    return class_getSuperclass((Class)self);  

superclass  
{  
    return class_getSuperclass(isa);  

+ superclass
{
    return class_getSuperclass((Class)self);
}
superclass
{
    return class_getSuperclass(isa);
}

9

1.2.12 conformsTo:

返回是否遵循了某个协议

static class_t * getSuperclass(class_t *cls) 

    if (!cls) return NULL
    return cls->superclass; 

0

最终用的是class_conformsToProtocol,返回一个布尔值,表示一个类是否符合给定的协议。

class_conformsToProtocol的实现如下:

static class_t * getSuperclass(class_t *cls) 

    if (!cls) return NULL
    return cls->superclass; 

1

可以看到是在cls->protocols里面找.protocols是协议的数组

1.2.13 copy

浅拷贝

static class_t * getSuperclass(class_t *cls) 

    if (!cls) return NULL
    return cls->superclass; 

2

2 概念原理

2.1 野指针与僵尸对象

2.1.1 野指针

C语言:

当我们声明1个指针变量,没有为这个指针变量赋初始值.这个指针变量的值是1个垃圾指指针,指向1块随机的内存空间。

OC语言:

指针指向的对象已经被回收掉了。这个指针就叫做野指针。

2.1.2 僵尸对象

僵尸对象: 

1个已经被释放的对象 就叫做僵尸对象.

2.2 nil/Nil/NULL/NSNull的区别

nil:指向oc中对象的空指针

Nil:指向oc中类的空指针

NULL:指向其他类型的空指针,如一个c类型的内存指针

NSNull:在集合对象中,表示空值的对象

若obj为nil:

[obj message]将返回NO,而不是NSException

若obj为NSNull:

[obj message]将抛出异常NSException

nil和NULL从字面意思来理解比较简单,nil是一个对象,而NULL是一个值,我的理解为nil是将对象设置为空,而NULL是将基本类型设置为空的。而且我们对于nil调用方法,不会产生crash或者抛出异常。

看一下用法

NSURL *url = nil;

Class class = Nil;

int *pointerInt = NULL;

nil是一个对象指针为空,Nil是一个类指针为空,NULL是基本数据类型为空。

3 参考链接

IOS中类和对象还有,nil/Nil/NULL的区别

http://blog.sina.com.cn/s/blog_5fb39f910101akm1.html

cancelPreviousPerformRequestsWithTarget not cancelling anoutstanding performSelector:withDelay

http://stackoverflow.com/questions/8697648/cancelpreviousperformrequestswithtarget-not-cancelling-an-outstanding-performsel

iOS设置 延迟执行 与 取消延迟执行 方法 以及对runloop初步认识

http://www.cnblogs.com/someonelikeyou/p/5509878.html

IOS关于取消延迟执行函数的种种。performSelector与cancelPreviousPerformRequestsWithTarget

http://blog.csdn.net/samuelltk/article/details/8994313

IOS -延迟执行performSelector和取消延迟执行cancelPreviousPerformRequestsWithTarget

http://www.cnblogs.com/HermitCarb/p/4740773.html

--------------------- 

作者:junbaozi 

原文:https://blog.csdn.net/junbaozi/article/details/79452135 

(0)

本文由 投稿者 创作,文章地址:https://blog.isoyu.com/archives/apishiyongxiliezhenglinsobjectzhuanti.html
采用知识共享署名4.0 国际许可协议进行许可。除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。最后编辑时间为:11 月 29, 2018 at 08:38 下午

热评文章

发表回复

[必填]

我是人?

提交后请等待三秒以免造成未提交成功和重复