__weak限定符变量在底层发生了什么?

3
通常情况下,weak 引用被用来避免应用程序对象图中的保留循环。我理解这个部分。现在我想更深入地了解它们在幕后是如何工作的。
稍微查找了一下,我发现当我使用 __weak 限定符时,与该限定符相关联的变量会在自动释放池中注册,但这意味着什么?为什么要在池中注册对象?使用了什么类型的池?是主池还是其他特别创建的池?
当我使用以下代码:
id _weak myWeakObj = [[NSObject alloc] init];

编译器给了我一个警告,可以用以下方法解决:
id _strong myStrongObj =  [[NSObject alloc] init];
id _weak myWeakObj = myStrongObj;

因此,基于之前的问题,myStrongObj所引用的对象会发生什么?如果可能的话,我想知道编译器的代码是什么样子的?


1
实际的中间(后ARC)步骤并不真正作为源代码提供。您必须查看汇编程序以查看插入的保留和释放。不过,这是一个非常好的问题! - jscs
1
你在哪里读到关于autorelease池和__weak的内容?这并不是那样的。基本上这一切都由Objective-C运行时处理。我会尽快概括回答... - mattjgalloway
@JacquesCousteau 感谢您的点赞和修正标题。如何在汇编语言中使用保留和释放?谢谢。 - Lorenzo B
1
能否在编译时看到 ARC 对我们代码所做的更正?请参见 https://dev59.com/rWkv5IYBdhLWcg3wsCpO - jscs
1个回答

5
以下是您的朋友: 并且这是Objective-C运行时的源代码: 特别是,请看: 如果按照第一个链接中所述查看objc_initWeakobjc_destroyWeak,则可以了解其如何在“引擎盖下”工作。注册弱引用的关键在于weak_register_no_lock,注销弱引用的关键在于weak_unregister_no_lock
我将让您自己去了解它实际上是如何工作的:-)。

那么,当我使用 _weak 时,没有自动释放池参与,这是真的吗?或者编译器是否有可能添加一些神奇的指令来创建它?你所说的“不是这种情况”,是指我的代码片段吗? - Lorenzo B
2
自动释放池对__weak没有影响。可能仍然存在自动释放池。实际上,当您加载弱引用(请参见objc_loadWeak)时,它会保留并自动释放对象。但是在这里您不需要担心自动释放池-它与__weak变量的工作方式无关。 - mattjgalloway
非常感谢您的回复。最后一个问题。在 objc_loadWeak 中,写道如果对象被注册为__weak对象,并且最后一个存储在对象中的值尚未被释放或开始释放,则保留该值并返回它。您能解释一下这句话的意思吗?再次感谢。 - Lorenzo B
3
这意味着它会保留对象,并且仅当对象未被释放或正在被释放时才返回该对象。也就是说,它总是会返回一个有效的对象,或者返回 nil。 - mattjgalloway
@flexaddicted,但是为什么编译器会保留那个对象并返回它,如果我们明确使用了__weak限定符呢? - AndrewShmig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接