View 持有强引用?

Posted

技术标签:

【中文标题】View 持有强引用?【英文标题】:View's holding strong references? 【发布时间】:2012-08-21 18:01:33 【问题描述】:

快速提问:我的ViewController 有一个IBOutlet 对应一个UILabel ViewController's view 会自动持有对标签的强引用吗?而且,如果我以编程方式在ViewController 中创建UIPopoverController ivar 并以编程方式将UIPopoverController ivar 放在屏幕上,ViewController's view 是否也会自动保持对它的强引用?

【问题讨论】:

【参考方案1】:

您应该保留对不属于视图层次结构的任何视图的强引用。您的视图控制器已经对其view 属性(主视图)具有强引用,并且所有子视图都将由其父视图保留,因此您实际上不需要对它们进行强引用,您可以对它们进行弱引用那些观点。

但是,如果您有任何不在主视图中的视图(例如,在 .xib 文件中定义的附加视图,您稍后可能会添加到主视图中,或者您的子视图之一想要以编程方式删除和重新添加),那么您应该强烈引用这些视图。

还请注意,当您在视图控制器中持有对视图的强引用时,您应该在 viewDidUnload 中设置 self.strongViewRef = nil,因为在卸载视图时不需要它(例如,当视图控制器在背景中,例如被另一个全屏视图遮挡)。再次加载视图时,该属性将自动重新设置为该视图的新实例。

关于弹出框,它会在呈现时保留(我认为是window),但我建议在需要时保持对它的强引用,然后将指针设置为nil完成它。这样,您就可以保证您可以在需要时访问它,在某些情况下,可能是在它呈现之前或在它被关闭之后。

【讨论】:

谢谢!因此,仅当UIToolBar 上的按钮(工具栏是view 的子视图)上的按钮时才会出现弹出框。此外,弹出框是通过编程方式创建并放置在视图上的。这是否意味着它是ViewController 的子视图而不是ViewController's view 的子视图? 弹出框不是视图控制器的子视图。 Popover 实际上是一种视图控制器本身(虽然它不是从UIViewController 继承的)。它拥有您的一个视图控制器,它有自己的视图,您的视图控制器也是如此,因此弹出框控制器将拥有自己的视图并将您的视图控制器的视图添加到自己,然后直接在窗口上呈现自己(不在呈现中VC的观点)。您从中呈现它的控制器应该持有对弹出框控制器的强引用,并且可能也是它的委托,以便您知道它何时被解除。 是的,单独的视图控制器只管理它们自己的视图层次结构(除非您正在编写容器控制器,这是一个非常高级的主题)。例如,导航控制器是一种容器控制器(它呈现和显示其他视图控制器)。因此,如果您从 viewControllerA(在导航控制器中)执行 [self.navigationController pushViewController:viewControllerB animated:YES],则 B 的视图层次结构与 A 没有任何关系,但是导航控制器会将 B 的视图放入自己的视图中,并在转换完成后删除 A 的视图.【参考方案2】:

Apple suggests 现在保存对通过界面构建​​器创建的视图的弱引用,除了根单一视图层次结构将负责保留视图

但是,如果您手动创建它,您希望在将新创建的视图添加到视图层次结构之前至少具有局部强变量,然后您可以将其分配给弱 ivar,这样它就不会在分配给后立即丢失弱ivar,例如:

// Somewhere in .h
__weak UIView *_myView;

// Somewhere in .m
_myView = [[UIView alloc] init];
[self.view addSubview:_myView];

没有多大意义,_myView会立即丢失

// Somewhere in .h
__weak UIView *_myView;

// Somewhere in .m
UIView *myLocalView = [[UIView alloc] init];
[self.view addSubview:myLocalView];
_myView = myLocalView;

非常安全,因为您分配了一个由视图层次结构本身管理的变量

UIPopoverController,另一方面,根据文档,您应该始终保留(例如 __strong ivar)。不仅如此,如果您不保留它,您将遇到一个令人讨厌的错误。

【讨论】:

【参考方案3】:

你不需要让出口变得强大,因为视图控制器应该被强烈持有,一旦它消失,就没有理由坚持出口,因为视图不再存在,所以出口弱是美好的。视图本身拥有指向它们的强指针。

编辑:抱歉忘了说是的,你应该保持指向 popovercontroller 的强指针

【讨论】:

以上是关于View 持有强引用?的主要内容,如果未能解决你的问题,请参考以下文章

iOS中的强代理(strong delegate)

【OC语法】block的循环引用

block浅析与使用block导致循环强引用举例

强引用

EntityManager 是不是持有对分离实体的引用?

JVM如何理解强引用软引用弱引用虚引用?