何时应该在IBOutlets中使用Strong vs Weak(进一步澄清)

14
我曾经从这个问题中清楚地理解过 --> Should IBOutlets be strong or weak under ARC?,但最近我进行了一次讨论,使我完全困惑了。请问有人能否确认以下内容是否正确?(如果这是一个重复的问题,我并不是要违反任何规则..只是需要澄清,因为我比文字更能理解图表..)
在ARC下(MacOSx):
1. view1 = strong 2. MainView = weak (在WindowControllerA中) 3. MainView = strong(在ViewControllerB中) 4. view2 = strong 5. view3 = weak (在ViewcontrollerB中) 6. view3 = strong(在ViewControllerC中)
如果这是正确的,请有人确认一下。
在上面的图示中,我们有一个位于屏幕上的windowControllerA。在windowControllerA的视图中,有两个NSViews。view1属于windowController,但mainView属于实例化的视图控制器ViewControllerB的视图。
ViewControllerB还包含其mainView内的2个视图。view2由viewControllerB拥有,而view3属于另一个已实例化的视图控制器ViewControllerC。
ViewController C有一个它所拥有的视图。
3个回答

19
大多数子视图的输出口不需要强引用,因为它们在视图层次结构中作为子视图加载。只要顶级视图存在,并且您不删除子视图的父级,视图层次结构中的子视图将由其父级保留,直到顶级视图的生命周期结束。
在ARC之前的日子里,有些人很高兴依靠视图层次结构来保留他们的视图,因此将其输出口属性设置为“assign”。另一些人不喜欢这个想法,认为视图层次中的错误可能会导致他们拥有一些悬空指针,因此将其属性设置为“retain”。ARC为我们提供了零化弱引用,这样,如果它们指向的对象被解除分配,您的输出口将被设置为“nil”,这使得使用弱引用的输出口似乎更加安全。另一方面,如果您希望即使包含它的视图层次结构被解除分配,仍然维护对视图的引用,则应将该引用设置为“strong”。
由于您的视图控制器负责管理(即“拥有”)其管理的视图层次结构,因此应将其对顶级视图的引用设置为“strong”。您不需要太担心这一点,因为任何UIViewController派生的视图控制器的“view”属性都设置为“retain”(即“strong”)。

嗨,Caleb,所以在上面的图表中...哪个应该是强/弱?我不想“不用担心”,因为我希望理解它。我只需将顶层对象设置为强引用,并将其他所有内容设置为弱引用吗? - Just a coder
@Jai 我说过你“不需要担心”,因为UIViewController的view属性已经是强引用。换句话说,你不需要做任何特殊的事情来使它发生。就像我上面所说的,除非你想保留一个视图,即使其余的视图图形被解除分配,否则子视图的outlets可以是弱引用。我无法完全理解你的图表,所以不会对此发表评论。 - Caleb
@Caleb 所以如果一个 IBOutlet 被设置为 strong,它将会保持在内存中。但是我们如何访问这个内存呢? - resting

2
只要我理解了这个"All the top-level objects should be strong. And subviews should be weak",那么在这种情况下,view2也应该是弱引用
  • view1 = 强引用
  • MainView = 弱引用 (在WindowControllerA中)
  • MainView = 强引用 (在ViewControllerB中)
  • view2 = 弱引用 (因为mainview已经持有它了)
  • view3 = 弱引用 (在ViewcontrollerB中)
  • view3 = 强引用 (在ViewControllerC中)

谢谢。根据我上面提出的问题,你的答案是正确的。但是我决定改变设置,并选择下面的答案,因为它更加详细。 - Just a coder

0

关于在“文件所有者”的IBOutlets中弱引用和强引用.xib对象的讨论太多了,而且似乎每个人都只关心视图和子视图。

子视图由它们的父视图拥有,只要您不以编程方式拆除视图层次结构(并对视图所有权负责),您就不需要过多担心。

但是,那些您经常在.xibs中创建的其他对象,例如NSArrayControllers和那些不是视图的根级UI项,例如Windows、Panels、Alerts等等,它们应该被引用为强引用还是弱引用?

我真的需要一些关于xibs工作原理的低级解释。当一个对象是“文件所有者”并加载其nib文件时,会加载和初始化什么?只加载您具有IBOutlets的对象吗?每个顶级对象都加载吗?

谁拥有所有这些根级对象?毕竟,加载nib的控制器(通常是“文件所有者”)拥有.xib --- 但这是否意味着它自动拥有nib中的根级对象?

如果是这样的话,如果您对.xib对象有一个弱IBOutlet引用、强引用或根本没有引用,有什么区别----对于该对象,您仍然是“文件所有者”,

有更好的解释就行。


数组控制器等应该是强引用。关键在于 XIB 中元素的出口需要是强引用,除非它们是视图层次结构的一部分并由其父视图/父窗口持有,但通常你链接的大多数元素都是这样的,因此只有来自 XIB 的不相关对象(如其他控制器)需要是强引用。 - Kuba Suder
1
当您加载NIB时,图表上的所有元素都会被加载到内存中,但如果它们没有被任何东西保留,那么它们将立即被释放。视图/窗口中的控件由其父级保留,但独立元素必须使用强IBOutlet进行保留。 - Kuba Suder
谢谢,这很清晰易懂。不过,在早期,当我们没有“属性”且每个人都将其控制器的普通成员用作IBOutlets时,我不记得在我的“awakeFromNib”等中保留任何IBOutlet成员,那么谁拥有顶级NIB对象呢? - Motti Shneor

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