我想更好地理解strong
和weak
指针的实现,并且我想出了关于他们的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
}
这是我的构造假设,强大的定位器可能看起来像。所以,我的第一个问题是 - 我的假设是否正确?
第二,弱参考。我猜,它应该看起来相似,但排除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
减少,当变量的方法结束时?
我知道很多开发人员都很熟悉这个问题,但我希望在这种情况下做出澄清。感谢。
答案 0 :(得分:2)
您的强有力的实施是正确的。
弱者是错的。如果您之前没有保留该值,则不允许释放该值。您只需设置新值而不在此处发出内存管理调用。
然后,那不会真的很弱,但是分配。关于weak的特殊之处在于引用被引用的对象被清零。
答案 1 :(得分:1)
对于第一和第二个问题,请参阅@ rmaddy的评论和克里斯蒂安的答案。
所以,实际上我想知道,当自己的变量完成的方法时,每次保留计数是否递减?
首先,我想要更精确:当你说"当拥有变量的方法完成时#34;你可能意味着"当自动存储类的本地强引用变量失去其范围时#34;。这不完全一样。但这可能是你想说的。 ("通常的本地变种")
在这种情况下,引用的对象被释放是正确的。
但事情在幕后更加困难。 I. e。:如果返回本地var(再次更精确:引用的对象)会发生什么?如果方法是所有权转移,在这种情况下会发生什么?
基本问题是自动引用计数必须正式考虑边缘情况,即使在"通常"代码事物无法破灭。一个人类开发人员可以说:"哦,有一个非常特殊的情况,代码可以打破,但我知道这永远不会发生。"编译器不能。因此ARC通常会创建非常多的内存处理调用。幸运的是,其中许多都被优化了。
如果您想深入了解在哪种情况下所做的事情,您有两个好方法:
阅读clang's documenation,这比Apple目前更精确,但它更复杂。
在单独的文件中创建一个类,该文件实现手动引用计数(-retain
,-release
,...)的方法并记录执行。然后使用手动引用计数进行编译,这可以通过编译器标志来实现。在ARC代码中使用该类。你会看到,ARC做了什么。 (你不应该依赖于结果,因为它们是优化的主题,战略可以在未来发生变化。但它是理解ARC工作原理的好工具。)