关于ObjectC引用计数的粗糙解释

引用计数,oc进行内存管理的一个技术。此计数记录了一个对象被指针指向的次数。提到指针,很多书籍都将指针比喻成牵牛的绳子。那oc种的牵牛绳牵的是一头很聪明的牛,当它察觉到自己身上不再有绳子牵着的时候就会跑掉,更神奇的是自个儿跑回牛棚里(对应的概念就是当引用计数为0的时候,内存被释放,释放的内存可被系统再分配)。

现在我们自己实现这一简单的功能,选择用c++的原因是,c++有操作符重载,以及析构函数。这对于我们要实现的简陋内存管理是非常方便的.

首先根类NSObject的代码如下:

class NSObject
{
public:
    int refereceCount_;
public:
    NSObject()
    {
        refereceCount_ = 0;
    }
    NSObject(int _ix)
    {
        refereceCount_ = 0;
    }
    NSObject(string name)
    {
        refereceCount_ = 0;
        name_          = name;
    }
    ~NSObject()
    {
        cout <

两个成员变量 refereceCount_ 和 name_,分别是引用计数和对象标识。引用计数存放在对象里的原因显而易见,因为这样只需保持一份,一处更改处处生效。如果存放在指针中,就存在更新引用计数要一同更新多个副本的问题。
指针类:

class Pointer
{
public:
    virtual Pointer& operator = (NSObject * pt) = 0;
    virtual ~Pointer()
    {
        
    }
};

指针类要实现两个功能,一是指向对象,二是指针相互赋值。这里就是重载了赋值操作符实现的。主要看看这个StrongPointer:

class StrongPointer:public Pointer
{
public:
    Pointer& operator = (NSObject * pt)
    {
        pt2Object_ = pt;
        if(pt != NULL)
            pt->refereceCount_ ++;
        cout << "强绳子套住 ("<name_<<") ,引用计数加1,此时的引用计数为 "<refereceCount_<refereceCount_ --;
            cout << "绳子将要被解除 ,(" <name_<<") 引用计数减1,此时的引用计数为 "<refereceCount_<refereceCount_ == 0)
                delete pt2Object_;
        }
        pt2Object_ = pointer.pt2Object_;
        if(pt2Object_ != NULL)
            pt2Object_->refereceCount_ ++;
        
        cout << "强绳子套住 (" <<  pointer.pt2Object_->name_<<"),引用计数加1,此时的引用计数为 "<refereceCount_<refereceCount_ --;
            cout << "绳子将要被解除 ,(" <name_<<") 引用计数减1,此时的引用计数为 "<refereceCount_<refereceCount_ == 0)
                delete pt2Object_;
        }
        pt2Object_ = pointer.pt2Object_;
        if(pt2Object_ != NULL)
            pt2Object_->refereceCount_ ++;
        
        cout << "强绳子套住 (" <<  pointer.pt2Object_->name_<<"),引用计数加1,此时的引用计数为 "<refereceCount_<refereceCount_ --;
        
        if(pt2Object_->refereceCount_ == 0)
        {
            cout << "强绳子被解除, ("<name_<<") 引用计数减1,此时引用计数为0"<name_<<") 引用计数减1,此时的引用计数为 "<refereceCount_ <

主要看以下两个函数
Pointer& operator = (NSObject * pt) 和 StrongPointer& operator = (const StrongPointer &pt) 分别接受对象(虽然这里实际上还是对象的指针,这个指针是c++概念里的指针,StrongPointer类的对象才是我们要表示这个牵牛绳的物件。)
和另一个指针类实体。 所做的事情也很简单 ,将所指向的对象的引用计数加一。_refereceCount设为公有是很不负责任的行为,但是为了方便,暂且就这么做了。

另外一个重要的点就是这个析构函数,当指针类自身被销毁的时候,也就是牵牛绳不在了的时候,牛是要记住自己身上的牵牛绳少了一根的,特别的,当牵牛绳统统都不见了,牛就跑回牛棚(内存被系统回收.)

测试看下结果:

StrongPointer  s_pt1 ;
    s_pt1                 = new NSObject("黄牛");
    
    StrongPointer * s_pt2 = new StrongPointer();
    *s_pt2                = new NSObject("黑牛");
1.jpeg

可以看到的是 我们找来了两个 “绳子” ,s_pt1,spt_2。这两个"绳子"分别来自栈和堆,当程序运行结束时 栈上的“绳子”就会被自动解除,于是它栓的牛也就跑了

看另外一段代码:

StrongPointer  s_pt1 ;
    s_pt1                 = new NSObject("黄牛");
    
    StrongPointer * s_pt2 = new StrongPointer();
    *s_pt2                = new NSObject("黑牛");
    
    *s_pt2                = s_pt1;
2.jpeg

同样还是两根绳子,原本是黄牛跑回了牛棚,这次我们将原本栓在黑牛身上的绳子拴在了黄牛身上,于是黑妞就当场跑了。黄牛身上有两个绳子,一个会自动销毁,一个不会,于是最后黄牛还是会被拴在原地。

你可能感兴趣的:(关于ObjectC引用计数的粗糙解释)