我使用ARC专门为iOS 5开发游戏。iboutlet到UIViews(和子类)是强还是弱?

以下几点:

@property (nonatomic, weak) IBOutlet UIButton *button;

就能摆脱这一切

- (void)viewDidUnload
{
    // ...
    self.button = nil;
    // ...
}

做这个有什么问题吗?模板使用强,当从“接口生成器”编辑器直接连接到头部时,自动生成的属性创建,但为什么?UIViewController已经有一个强引用到它的视图,它保留了它的子视图。


当前回答

警告,过时的答案:根据WWDC 2015,这个答案不是最新的,正确答案参考上面的公认答案(丹尼尔·霍尔)。这个答案将被记录下来。


从开发人员库总结:

From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because: Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership. The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet). @property (weak) IBOutlet MyView *viewContainerSubview; @property (strong) IBOutlet MyOtherClass *topLevelObject;

其他回答

我认为最重要的信息是: xib中的元素自动位于view的子视图中。Subviews是NSArray。NSArray拥有它的元素。等等都有强指针。所以在大多数情况下你不需要创建另一个强指针(IBOutlet)

使用ARC,你不需要在viewDidUnload中做任何事情

出于性能考虑,IBOutlet应该是强大的。参见iOS 9中的故事板参考,Strong IBOutlet, Scene Dock

As explained in this paragraph, the outlets to subviews of the view controller’s view can be weak, because these subviews are already owned by the top-level object of the nib file. However, when an Outlet is defined as a weak pointer and the pointer is set, ARC calls the runtime function: id objc_storeWeak(id *object, id value); This adds the pointer (object) to a table using the object value as a key. This table is referred to as the weak table. ARC uses this table to store all the weak pointers of your application. Now, when the object value is deallocated, ARC will iterate over the weak table and set the weak reference to nil. Alternatively, ARC can call: void objc_destroyWeak(id * object) Then, the object is unregistered and objc_destroyWeak calls again: objc_storeWeak(id *object, nil) This book-keeping associated with a weak reference can take 2–3 times longer over the release of a strong reference. So, a weak reference introduces an overhead for the runtime that you can avoid by simply defining outlets as strong.

在Xcode 7中,它是强的

如果你观看了WWDC 2015会议407在界面生成器中实现UI设计,它建议(来自http://asciiwwdc.com/2015/sessions/407)

And the last option I want to point out is the storage type, which can either be strong or weak. In general you should make your outlet strong, especially if you are connecting an outlet to a sub view or to a constraint that's not always going to be retained by the view hierarchy. The only time you really need to make an outlet weak is if you have a custom view that references something back up the view hierarchy and in general that's not recommended. So I'm going to choose strong and I will click connect which will generate my outlet.

我想在这里指出一件事,那就是,尽管苹果工程师在他们自己的2015年全球开发者大会视频中说过:

https://developer.apple.com/videos/play/wwdc2015/407/

苹果公司在这个问题上一直在改变主意,这告诉我们这个问题没有唯一的正确答案。为了证明就连苹果的工程师在这个问题上也存在分歧,看看苹果最近的一份报告就知道了 示例代码,你会看到有些人使用weak,有些人不用。

这个Apple Pay的例子使用了weak: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElementID_8

下面这个图中图的例子也是如此: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_PlayerViewController_swift-DontLinkElementID_4

就像Lister的例子一样: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57

核心位置的例子也是如此: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElementID_6

视图控制器预览示例如下: https://developer.apple.com/library/ios/samplecode/ViewControllerPreviews/Listings/Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift.html#//apple_ref/doc/uid/TP40016546-Projects_PreviewUsingDelegate_PreviewUsingDelegate_DetailViewController_swift-DontLinkElementID_5

HomeKit的例子也是如此: https://developer.apple.com/library/ios/samplecode/HomeKitCatalog/Listings/HMCatalog_Homes_Action_Sets_ActionSetViewController_swift.html#//apple_ref/doc/uid/TP40015048-HMCatalog_Homes_Action_Sets_ActionSetViewController_swift-DontLinkElementID_23

所有这些都是针对iOS 9完全更新的,并且都使用弱outlet。这个问题并不像有些人想的那么简单。B.苹果一再改变主意,C.你可以用任何让你高兴的东西:)

特别感谢Paul Hudson (www.hackingwithsift.com的作者),他给了我澄清,以及这个答案的参考资料。

我希望这能更好地阐明主题!

当心

警告,过时的答案:根据WWDC 2015,这个答案不是最新的,正确答案参考上面的公认答案(丹尼尔·霍尔)。这个答案将被记录下来。


从开发人员库总结:

From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File’s Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create will therefore typically be weak by default, because: Outlets that you create to, for example, subviews of a view controller’s view or a window controller’s window, are arbitrary references between objects that do not imply ownership. The strong outlets are frequently specified by framework classes (for example, UIViewController’s view outlet, or NSWindowController’s window outlet). @property (weak) IBOutlet MyView *viewContainerSubview; @property (strong) IBOutlet MyOtherClass *topLevelObject;

从WWDC 2015开始,有一个关于在界面生成器中实现UI设计的会议。在第32分钟左右,他说你总是想让你的@IBOutlet强大。