弱和强 属性 实施

Weak and strong property implementation

我想更好地理解 strongweak 指针的实现,并且我想出了关于它们的 setter 方法的假设(如果我错了请纠正我) .

首先,强指针,看起来像:

- (void)setObj:(NSObject*)Obj   // Setting Strong Obj
{
    //First, check either we trying to set old value again

    if (_Obj == Obj)
    {
        return;
    }

    NSObject* oldObj = _Obj;
    _Obj = [Obj retain];
    [oldObj release];

    // Set pointer to old "chunk" of memory, containing old value, 
    // assign new value to backed instance variable and release
    // old value    
}

那是我的构造假设,强 setter 可能看起来像。所以,我的第一个问题是 - 我的假设是否正确?

第二,弱引用。我想,它看起来应该相似,但不包括 retain.

- (void)setObj:(NSObject*)Obj   // Setting Weak Obj
{
    if (_Obj == Obj)
    {
        return;
    }

    NSObject* oldObj = _Obj;
    _Obj = Obj; // setting value without incrementing reference count
    [oldObj release];
}

关于 weak 参考工作的假设是否正确?

好的,还有一个问题。考虑这样的情况(在手动内存管理中):

- (void)testFunc
{    
    strongObj = val; // Retain count about >= 2
    weakObj = val; // Retain count about >=1
}

// Now strongObj lives in memory with value of val, with retain count >=1
// weakObj is destroyed, since after end of a scope (function body) it retain count decreased by 1

所以,其实我想知道,retain count是否每次递减,当拥有变量的方法完成时?

我知道这个问题对很多开发人员来说都很熟悉,但是,在那种情况下我想澄清一下。谢谢。

你的强执行是正确的。

弱者错了。如果您之前未保留该值,则不允许释放该值。您只需在此处设置新值而无需发出内存管理调用。

话又说回来,那不是真的很弱,而是赋值。 weak 的特殊之处在于引用被清零,被引用的对象被释放。

对于第一个和第二个问题,我参考了@rmaddy 的评论和 Christian 的回答。

So, actually i want to know, whether retain count decremented each time, when method that own variable finishes?

首先,我想更准确地说:当你说 "when method that own a variable finishes" 时,你可能指的是 "when a local strong reference variable of automatic storage class loses its extent"。这并不完全相同。但这可能是你想说的。 ("A usual local var.")

在这种情况下,引用的对象被释放是正确的。

但幕后的事情更难。即:如果返回局部变量(再次更精确:引用的对象)会发生什么?在这种情况下会发生什么,如果该方法是所有权转让或不是?

基本问题是自动引用计数必须正式考虑边缘情况,即使在 "usual" 代码中也不能破坏。人类开发人员可以说:"Oh, there is a very special situation the code can break, but I know that this never happens." 编译器不能。所以 ARC 通常会创建非常多的内存处理调用。幸运的是,其中许多都被优化掉了。

如果你想深入了解在什么情况下做了什么,你有两个好方法:

  1. 阅读clang's documenation,目前比Apple的更精确,但更复杂。

  2. 在单独的文件中创建一个 class 来实现手动引用计数的方法(-retain-release、…)并记录执行。然后使用手动引用计数对其进行编译,这可以通过编译器标志实现。在 ARC 代码中使用 class。您将看到 ARC 的作用。 (你不应该依赖结果,因为它们是优化的主题,策略在未来可能会改变。但它是理解 ARC 工作原理的好工具。)

从气球的角度考虑强引用和弱引用可能会有所帮助。

只要至少有一个人拉着系在气球上的一根绳子,气球就不会飞走。持有字符串的人数是保留计数。当没有人抓住一根绳子时,气球就会飞走(dealloc)。很多人都可以用绳子系同一个气球。您可以 get/set 使用强引用和弱引用对被引用对象的属性和调用方法。

强引用就像抓住气球上的一根绳子。只要你拉着气球上的绳子,它就不会飞走。

弱引用就像看气球。你可以看到它,访问它的属性,调用它的方法,但是你没有那个气球的字符串。如果拉着绳子的人都松手,气球就会飞走,你就不能再靠近了。