'defer' in this example means something different than 'defer' as used in Swift 
today. I would expect a 'defer init()' to be called immediately before the main 
initializer goes out of scope, like how a defer block works today, but this 
defer init() must be called when the main initializer first comes into scope 
(before the super call).

I don't think there's a clarity gain here. If I retroactively add an 
initializer to a class I don't have access to via an extension, how do I know 
whether or not a defer initializer I can't see is being called, or what it's 
doing? What if I want common initializer code after the super.init call? For 
symmetry, do we need 'predefer' and 'postdefer'? How do defer init()s interact 
with access control - can I silently break my initializer just by changing its 
access control level?

A static function that initializers can call, however, has the notable benefit 
of behaving the exact same way as a static function anywhere else in code while 
still respecting the complex init member usage rules.

Austin

> On Apr 30, 2016, at 11:30 AM, Basem Emara via swift-evolution 
> <[email protected]> wrote:
> 
> Hey Hooman, that’s very elegant. I didn’t think of it like that and will 
> definitely use, thx!
> 
> Though wouldn’t “defer init()” take it a step further: 1) reduce redundant 
> boilerplate 2) prevent forgetting/bugs and 3) smaller memory allocation 
> footprint? It also fits well with the existing Swift 2 “defer” keyword used 
> in functions. Here’s what your sample would look like:
> 
> import UIKit
> import AVFoundation
> 
> class SomeViewController: UIViewController {
>     
>     // MARK: Properties
>     
>     private var videoPlayer: AVPlayer
>     private var videoPlayerLayer: AVPlayerLayer
>     
>     // MARK: - Object Lifecycle
>     
>     override init(nibName: String?, bundle nibBundle: NSBundle?) {
> 
>         super.init(nibName: nibName, bundle: nibBundle)
>     }
>     
>     required init?(coder decoder: NSCoder) {
>         
>         super.init(coder: decoder)
>     }
>    
>     defer init() {
>         videoPlayer = AVPlayer(URL: NSURL(fileReferenceLiteral: "movie.mov"))
>         videoPlayerLayer = AVPlayerLayer(player: player)
>     }
> }
> 
>> On Apr 30, 2016, at 2:18 PM, Hooman Mehr via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> Besides the ages old designated initializer pattern that is already 
>> suggested (having a few designated initializers and a bunch of convenience 
>> initializers), this is how I have been dealing with this since Swift 1.0:
>> 
>> import UIKit
>> import AVFoundation
>> 
>> class SomeViewController: UIViewController {
>>     
>>     private typealias My = SomeViewController
>>     
>>     // MARK: Properties
>>     
>>     private var videoPlayer: AVPlayer
>>     private var videoPlayerLayer: AVPlayerLayer
>>     
>>     // MARK: - Object Lifecycle
>>     
>>     override init(nibName: String?, bundle nibBundle: NSBundle?) {
>> 
>>         
>>         (videoPlayer, videoPlayerLayer) = My.commonInitialization()
>> 
>>         super.init(nibName: nibName, bundle: nibBundle)
>>     }
>>     
>>     required init?(coder decoder: NSCoder) {
>>         
>>         (videoPlayer, videoPlayerLayer) = My.commonInitialization()
>> 
>>         super.init(coder: decoder)
>>     }
>>     
>>     
>>     private static func commonInitialization() -> (AVPlayer, AVPlayerLayer) {
>>         
>>         let player = AVPlayer(URL: NSURL(fileReferenceLiteral: "movie.mov"))
>>         let layer = AVPlayerLayer(player: player)
>>         
>>         return (player,layer)
>>     }
>> }
>> 
>> It is not perfect, but good enough for me.  I usually use this when I have 
>> more than one designated initializer and they share a significant amount of 
>> code. I usually also have input parameters for this commonInitialization 
>> static or class method. I make it a class method when I anticipate 
>> subclassing of the class.
>> 
>> Side Note: As you see, I typically define a couple of private type aliases 
>> (Usually `I` and/or `My`) to help with readability of code involving static 
>> members.
>> 
>>> On Apr 27, 2016, at 2:52 PM, Shannon Potter via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> Consider a relatively-common init pattern:
>>> 
>>> class SomeViewController: UIViewController {
>>> 
>>>    // MARK: Properties
>>> 
>>>    private var videoPlayer: AVPlayer
>>>    private var videoPlayerLayer: AVPlayerLayer
>>> 
>>>    // MARK: - Object Lifecycle
>>> 
>>>    override init(nibName: String?, bundle nibBundle: NSBundle?) {
>>>        super.init(nibName: nibName, bundle: nibBundle)
>>> 
>>>        commonInitialization()
>>>    }
>>> 
>>>    required init?(coder decoder: NSCoder) {
>>>        super.init(coder: decoder)
>>> 
>>>        commonInitialization()
>>>    }
>>> 
>>>    private func commonInitialization() {
>>>        videoPlayer = AVPlayer(...)
>>>        videoPlayerLayer = AVPlayerLayer(player: videoPlayer)
>>>    }
>>> 
>>> }
>>> 
>>> This does not work. Both properties are non-optional, and the compiler 
>>> complains that they are not initialized in either init method. It seems 
>>> rather common to want a single point of contact regarding object 
>>> initialization, regardless of the path taken to initialize that object. 
>>> Ideally, objects could all be funneled to one designated initializer, but 
>>> this isn’t always the case.
>>> 
>>> What are people’s thoughts about either a specialized function that is 
>>> always called at the very end of each object’s lifecycle OR some sort of 
>>> attribute for a function that hints that the compiler should follow it if 
>>> called in an init function to check for property initialization?
>>> 
>>> func commonInit() {
>>> 
>>> }
>>> 
>>> or
>>> 
>>> @extend_init private func commonInitialization() {
>>> 
>>> }
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to