Objective c 在AppKit中开发时,为什么IB创建的属性是assign而不是retain?
我是一名经验丰富的iOS开发人员,我决定尝试一些AppKit开发。我在API方面做了一些调整,但在其他方面,我发现OSX开发是“熟悉的” 我一直在Interface Builder中构建AppKit UI,并注意到当我使用所见即所得编辑器在代码文件中创建属性时,Apple正在创建以下内容:Objective c 在AppKit中开发时,为什么IB创建的属性是assign而不是retain?,objective-c,memory-management,appkit,Objective C,Memory Management,Appkit,我是一名经验丰富的iOS开发人员,我决定尝试一些AppKit开发。我在API方面做了一些调整,但在其他方面,我发现OSX开发是“熟悉的” 我一直在Interface Builder中构建AppKit UI,并注意到当我使用所见即所得编辑器在代码文件中创建属性时,Apple正在创建以下内容: @property (assign) IBOutlet NSTableView *tableView; 我觉得这很奇怪,因为在iOS中默认的做事方式会让我这样做: @property (nonatomic,
@property (assign) IBOutlet NSTableView *tableView;
我觉得这很奇怪,因为在iOS中默认的做事方式会让我这样做:
@property (nonatomic, retain) IBOutlet NSTableView *tableView;
我意识到,在Mac开发中,我没有和在移动设备上一样的内存限制,在移动设备上,视图可能会被卸载,并且可能需要对UI元素进行强引用
在AppKit的情况下,我可以很好地假设我的UI元素将始终存在,除非我修改视图层次结构并将其从其父视图中删除。为了防止无意中访问悬空指针,在任何时候都使用强引用似乎是明智的
为什么苹果在这里创建的是弱引用,而不是强引用?
我是否通过使用强引用(但在
dealloc
中正确发布)为自己设置了一些意外后果?这里有我缺少的模式吗?作为文件的所有者,您应该拥有nib中的所有顶级对象。您通常不需要拥有这些对象中的任何对象,因为父对象将拥有其子对象;例如,窗口将拥有其视图
(这在@property
、合成访问器和ARC存在之前是有意义的。)因此,即使相关属性弱或不安全(后者是分配
的同义词),所有者实际上也将拥有顶级对象。如果你走另一条路,让这些属性strong
(又称保留),那么FO对每个对象有两种所有权:隐式所有权和strong
-属性所有权
假设您使用的是手动引用计数,您可以释放awakeFromNib
中的隐式所有权,但这只是工作而已。只要在加载nib后不替换任何这些对象(例如,将一个表视图替换为另一个表视图),则不安全的\u unrepaired
属性就可以正常工作,没有多余的保留或任何已完成的工作
但是,命名为“不安全”
是有原因的(对于对象属性,该名称优先于assign
)。返回窗口及其视图示例,假设您拥有一个窗口并了解其中一个视图。视图的superview可能是它的唯一所有者,因此,当您关闭窗口(或用户关闭窗口)时,视图将被释放,并因此解除分配。如果视图的属性是不安全的
/分配
,您仍然知道这个现在已死亡的对象,尝试向视图发送消息可能会导致崩溃或异常
您应该切换到ARC并将属性声明为弱
。这样,就不会创建多余的所有权,并且当视图消失时,属性将自动设置为nil
,从而防止过度发布崩溃的发生
(如果您不是文件的所有者,这些都不适用于您,您可能应该声明您认为合适的属性。弱
或强
可能是一个不错的选择,这取决于您对所有权层次结构的看法以及所引用的对象类型。)
在iOS上,UIKit的作者提出了现在存在问题的隐式保留。你要写自己的所有权;如果你想拥有一个nib或故事板上的对象,你就写了一个strong
属性,如果你只想知道它,你就写了一个weak
或safe\u unretained
属性,就像你所期望的那样
TL;DR:我担心这会是答案,但解释得很好。所以我们仍然需要[tableView release]
中的[tableView release]
?如果是这样,那么在使用ARC时,该release
何时会被调用?@MrMage:您通常不会拥有表视图,因为您通常会将其放在nib的窗口或容器视图中,而不会将其放在nib的顶层。您拥有窗口或顶级视图,只需了解表视图即可。您拥有的任何东西都必须释放。@MrMage:在ARC下,release
消息不存在:release
消息是非法的(如retain
和autorelease
)。这主要是因为ARC为您发布了强有力的参考资料;如果你被允许自己做这件事,ARC很难思考你在做什么。(这也是为什么它抱怨性能选择器:
,为什么@选择器(发布)
也是非法的。)没有发布
s的一个后果是,您很少需要编写解除锁定
——任何完全由[x发布]
消息组成的实现都会消失,编译器为您完成。@MrMage:至于反隐式保留(ARC不知道,因此无法平衡),我在回答中链接的文档建议使用CFRelease
。这完全是欺骗(在ARC背后),但这是处理nib加载程序在ARC下的隐式保留的唯一方法。