Should IBOutlets be strong or weak under ARC?

后端 未结 11 2136
自闭症患者
自闭症患者 2020-11-22 01:52

I am developing exclusively for iOS 5 using ARC. Should IBOutlets to UIViews (and subclasses) be strong or weak?

相关标签:
11条回答
  • 2020-11-22 02:30

    Be aware, IBOutletCollection should be @property (strong, nonatomic).

    0 讨论(0)
  • 2020-11-22 02:31

    While the documentation recommends using weak on properties for subviews, since iOS 6 it seems to be fine to use strong (the default ownership qualifier) instead. That's caused by the change in UIViewController that views are not unloaded anymore.

    • Before iOS 6, if you kept strong links to subviews of the controller's view around, if the view controller's main view got unloaded, those would hold onto the subviews as long as the view controller is around.
    • Since iOS 6, views are not unloaded anymore, but loaded once and then stick around as long as their controller is there. So strong properties won't matter. They also won't create strong reference cycles, since they point down the strong reference graph.

    That said, I am torn between using

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

    and

    @property (nonatomic) IBOutlet UIButton *button;
    

    in iOS 6 and after:

    • Using weak clearly states that the controller doesn't want ownership of the button.

    • But omitting weak doesn't hurt in iOS 6 without view unloading, and is shorter. Some may point out that is also faster, but I have yet to encounter an app that is too slow because of weak IBOutlets.

    • Not using weak may be perceived as an error.

    Bottom line: Since iOS 6 we can't get this wrong anymore as long as we don't use view unloading. Time to party. ;)

    0 讨论(0)
  • 2020-11-22 02:32

    The current recommended best practice from Apple is for IBOutlets to be strong unless weak is specifically needed to avoid a retain cycle. As Johannes mentioned above, this was commented on in the "Implementing UI Designs in Interface Builder" session from WWDC 2015 where an Apple Engineer said:

    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 subview 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.

    I asked about this on Twitter to an engineer on the IB team and he confirmed that strong should be the default and that the developer docs are being updated.

    https://twitter.com/_danielhall/status/620716996326350848 https://twitter.com/_danielhall/status/620717252216623104

    0 讨论(0)
  • 2020-11-22 02:34

    I think that most important information is: Elements in xib are automatically in subviews of view. Subviews is NSArray. NSArray owns it's elements. etc have strong pointers on them. So in most cases you don't want to create another strong pointer (IBOutlet)

    And with ARC you don't need to do anything in viewDidUnload

    0 讨论(0)
  • 2020-11-22 02:35

    It looks like something has changed over the years and now Apple recommends to use strong in general. The evidence on their WWDC session is in session 407 - Implementing UI Designs in Interface Builder and starts at 32:30. My note from what he says is (almost, if not exactly, quoting him):

    • outlet connections in general should be strong especially if we connect a subview or constraint that is not always retained by the view hierarchy

    • weak outlet connection might be needed when creating custom views that has some reference to something back up in the view hierarchy and in general it is not recommended

    In other wards it should be always strong now as long as some of our custom view doesn't create a retain cycle with some of the view up in the view hierarchy

    EDIT :

    Some may ask the question. Does keeping it with a strong reference doesn't create a retain cycle as the root view controller and the owning view keeps the reference to it? Or why that changed happened? I think the answer is earlier in this talk when they describe how the nibs are created from the xib. There is a separate nib created for a VC and for the view. I think this might be the reason why they change the recommendations. Still it would be nice to get a deeper explanation from Apple.

    0 讨论(0)
  • 2020-11-22 02:39

    One thing I wish to point out here, and that is, despite what the Apple engineers have stated in their own WWDC 2015 video here:

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

    Apple keeps changing their mind on the subject, which tells us that there is no single right answer to this question. To show that even Apple engineers are split on this subject, take a look at Apple's most recent sample code, and you'll see some people use weak, and some don't.

    This Apple Pay example uses weak: https://developer.apple.com/library/ios/samplecode/Emporium/Listings/Emporium_ProductTableViewController_swift.html#//apple_ref/doc/uid/TP40016175-Emporium_ProductTableViewController_swift-DontLinkElementID_8

    As does this picture-in-picture example: https://developer.apple.com/library/ios/samplecode/AVFoundationPiPPlayer/Listings/AVFoundationPiPPlayer_PlayerViewController_swift.html#//apple_ref/doc/uid/TP40016166-AVFoundationPiPPlayer_PlayerViewController_swift-DontLinkElementID_4

    As does the Lister example: https://developer.apple.com/library/ios/samplecode/Lister/Listings/Lister_ListCell_swift.html#//apple_ref/doc/uid/TP40014701-Lister_ListCell_swift-DontLinkElementID_57

    As does the Core Location example: https://developer.apple.com/library/ios/samplecode/PotLoc/Listings/Potloc_PotlocViewController_swift.html#//apple_ref/doc/uid/TP40016176-Potloc_PotlocViewController_swift-DontLinkElementID_6

    As does the view controller previewing example: 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

    As does the HomeKit example: 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

    All those are fully updated for iOS 9, and all use weak outlets. From this we learn that A. The issue is not as simple as some people make it out to be. B. Apple has changed their mind repeatedly, and C. You can use whatever makes you happy :)

    Special thanks to Paul Hudson (author of www.hackingwithsift.com) who gave me the clarification, and references for this answer.

    I hope this clarifies the subject a bit better!

    Take care.

    0 讨论(0)
提交回复
热议问题