为什么在子视图的@property中设置retain?

3

两个问题非常简单明了。

  1. 如果一个视图保留其子视图,并且我们在接口生成器中创建了一个视图层次结构,其中视图嵌套在其他视图中,为什么嵌套的子视图的IBOutlet属性需要设置为保留?对于这些子视图属性,分配不是一个可以接受的参数吗?

  2. 我有一个UIView子类,在初始化时向自身添加了一些子视图。为了捕获对特定子视图的引用,@property (nonatomic, assign)是否足够满足需求?例如,主UIView添加了一个播放器得分子视图,然后稍后想要与该播放器得分进行通信以更新它。只需要分配该引用,因为UIView类会自动保留该视图,对吗?


1
相关阅读:IBOutlet是否意味着weak? - jscs
啊,太好了。我觉得我已经充分阅读了苹果的文档,但答案就在那里。 - christopherdrum
2个回答

2

1) 没有必要使用retain,使用assign就可以了。你为什么认为一定要使用retain呢?

2) 是的。

顺便问一下,你使用的是ARC吗?如果是的话,请使用weak代替assign(请不要问为什么,在Stack Overflow和互联网的每个角落都有很好的解释)。


当前项目不是自动引用计数(ARC),所以我特别在保留/分配的上下文中提出了问题。感谢您考虑与我确认弱引用/强引用。我原本认为不必使用retain,但我意识到自己已经养成了这样的习惯,而且无法解释原因。当我开始质疑自己时,我意识到需要向整个社区确认。另一方面,我觉得开发人员经常被告知(例如通过在线教程)释放IBOutlets,这意味着要保留,这又反过来暗示了每个IBOutlet都必须始终保留。 - christopherdrum
任何一個網上教程告訴你總是釋放某些東西的話,都不值得信任。任何保留的屬性都必須被釋放,就像任何保留的IBOutlet一樣。IBOutlet除了視圖之外還可以用於其他事情,如果它是一個頂級對象,它將立即被解除保留而不成為保留屬性。 - borrrden

1

是的,在你的情况下,子视图将被视图保留,因此我们在技术上不需要再次保留它。然而,这有点脆弱。如果将来添加了一些从其父视图中删除该子视图的代码,那么除非您确保将其设置为nil,否则您将拥有一个悬空指针。

通常惯例是保留实例变量,除非有必要不保留(例如用于委托)。如果我们走向这样的道路:“哦,我们不需要保留这个实例变量,因为它在这里被保留了;哦,我们需要保留另一个实例变量,因为它没有被保留;等等”,那么我们最终会得到非常杂乱无章的内存管理,每次添加实例变量时,我们都必须考虑它是否被其他东西保留;然后每次使用它时,我们都必须记住我们是否决定保留它。这正是内存管理规则旨在避免的内存管理噩梦。

保留实例变量,它有什么害处呢?在这种情况下,当我们分配它时,它只会导致额外的保留和释放。为了简单和一致性的好处,这并不是什么大问题。


请考虑它是否被其他东西所保留。我谦虚地认为这正是我们应该思考的问题。事实上,上面链接中提到的苹果文档明确建议对不处于对象保留层次结构顶层的IBOutlets保持弱引用。 - christopherdrum

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