Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
375 views
in Technique[技术] by (71.8m points)

ios - How to implement two inits with same content without code duplication in Swift?

Assume a class that is derived from UIView as follows:

class MyView: UIView {
    var myImageView: UIImageView

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

    init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)
    }

    ...

If I wanted to have the same code in both of the initializers, like

self.myImageView = UIImageView(frame: CGRectZero)
self.myImageView.contentMode = UIViewContentMode.ScaleAspectFill

and NOT duplicate that code twice in the class implementation, how would I structure the init methods?

Tried approaches:

  • Created a method func commonInit() that is called after super.init -> Swift compiler gives an error about an uninitialized variable myImageView before calling super.init
  • Calling func commonInit() before super.init fails self-evidently with a compiler error "'self' used before super.init call"
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

What we need is a common place to put our initialization code before calling any superclass's initializers, so what I currently using, shown in a code below. (It also cover the case of interdependence among defaults and keep them constant.)

import UIKit

class MyView: UIView {
        let value1: Int
        let value2: Int

        enum InitMethod {
                case coder(NSCoder)
                case frame(CGRect)
        }

        override convenience init(frame: CGRect) {
                self.init(.frame(frame))!
        }

        required convenience init?(coder aDecoder: NSCoder) {
                self.init(.coder(aDecoder))
        }

        private init?(_ initMethod: InitMethod) {
                value1 = 1
                value2 = value1 * 2 //interdependence among defaults

                switch initMethod {
                case let .coder(coder): super.init(coder: coder)
                case let .frame(frame): super.init(frame: frame)
                }
        }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...