我是一名经验丰富的iOS开发人员,我决定尝试一些AppKit开发。我在API方面做了一些调整,但除此之外,我发现OS X的开发应该说是“熟悉的”。
我一直在界面生成器中构建我的AppKit UI,并注意到当我使用WYSIWYG编辑器在我的代码文件中创建属性时,苹果正在创建以下内容:
@property (assign) IBOutlet NSTableView *tableView;
我发现这非常奇怪,因为在iOS中默认的操作方式会导致我这样做:
@property (nonatomic, retain) IBOutlet NSTableView *tableView;
我意识到,在Mac开发中,我没有像在移动设备上那样的内存限制,在移动设备上,视图可能会被卸载,并且可能需要对UI元素进行强引用。
在AppKit的情况下,我可以很好地假设我的UI元素总是在那里,除非我摆弄视图层次结构并将其从其父视图中删除。为了防止无意中访问悬空指针,总是有一个强引用似乎是谨慎的。
为什么苹果在这里创建了一个弱引用,而不是一个强引用?
通过使用强引用(但在 dealloc
**)?中正确释放),我为自己设置了一些意外的后果这里有没有我遗漏的模式?**
发布于 2012-08-30 12:10:19
作为File的所有者,您应该拥有nib中的任何和所有顶级对象。您通常不需要拥有这些对象中的任何对象,因为父对象将拥有其子对象;例如,窗口将拥有其视图。
AppKit's nib loader implicitly retains all top-level objects on behalf of the File's Owner. (在@property
、综合访问器和ARC出现之前,这是有意义的。)因此,即使相关属性是weak
或unsafe_unretained
(后者是assign
的同义词),所有者实际上也将拥有顶级对象。如果您采用另一种方法,并将这些属性设置为strong
(也称为retain
),则FO具有每个对象的两个所有权:隐式所有权和strong
-property所有权。
假设您使用的是手动引用计数,您可以在awakeFromNib
中释放隐式所有权,但这是可行的。只要你不打算在加载nib后替换这些对象中的任何一个(例如,将一个表视图换成另一个表视图),unsafe_unretained
属性就可以很好地工作,而不会有多余的保留或任何工作。
尽管如此,unsafe_unretained
的命名是有原因的(对于对象属性,该名称比assign
更可取)。返回窗口及其视图的示例,假设您拥有一个窗口,并且知道它的一个视图。视图的superview可能是它的唯一所有者,因此,当您关闭窗口(或用户关闭它)时,视图将被释放,从而释放分配。如果视图的属性是unsafe_unretained
/assign
,那么您仍然知道这个现已死亡的对象,并且尝试向视图发送消息可能会导致崩溃或异常。
您应该切换到ARC并将该属性声明为weak
。这样,就不会创建多余的所有权,当视图终止时,该属性将自动设置为nil
,从而防止随后发生过度释放崩溃。
(如果您不是该文件的所有者,那么所有这些都不适用于您,您可能应该在您认为合适的时候声明您的属性。weak
或strong
可能是一个不错的选择,这取决于您如何看待所有权层次结构以及您引用的对象类型。)
在iOS上,UIKit的作者去掉了现在有问题的隐式保留。您需要编写自己的所有权;如果您想拥有一个来自nib或故事板的对象,您可以编写一个strong
属性,如果您只想知道它,那么您可以编写一个weak
或unsafe_unretained
属性,正如您所期望的那样。
TL;DR: Hysterical reasons.
https://stackoverflow.com/questions/12189439
复制相似问题