Swift Question

Why would a Swift UIView subclass with a convenience init() method start infinite looping after updating to Swift 3.0?

Here is some code from a project that, as you see it here, worked fine in Swift 2.3. Having now upgraded the project to Swift 3.0, this is producing an infinite loop at

self.init()
.

class MyView: UIView
{
fileprivate let foo: String

required init? ( coder aDecoder: NSCoder )
{
fatalError( "init( NSCoder ) has not been implemented" )
}

convenience init ()
{
self.init()
foo = "bar"
}
}


I am told this should have infinite looped in Swift 2.3 too. Fair enough, I believe it, all I am able to tell you is that it didn't, but I don't know why. The possible solutions suggested in this post - Initializing swift class in objective c project causes infinite loop - are not useful because:


  1. the
    convenience init()
    method in question really is a convenience
    init;

  2. self.init( frame: )
    produces the buildtime error message
    Incorrect argument label in call (have 'frame:', expected 'coder:')
    , and;

  3. I have no instance of
    NSCoder
    to pass into
    self.init( coder: )


Answer

The convenience init should always delegate the initialization to a designated initializer for the superclass, in this case the UIView. Unfortunately the only solution I found is to do this:

class MyView: UIView {

    fileprivate let foo: String = "bar"

    convenience init() {
        self.init(frame: .zero)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
Comments