【问题标题】:Swift Initialization - Why are multiple init functions being called?Swift Initialization - 为什么要调用多个 init 函数?
【发布时间】:2015-01-28 15:39:33
【问题描述】:

这是我的类,带有覆盖初始化

class BottomView: UIView {

    // MARK: - initilization

   override init() {
        println("init")
        super.init()
        setup()
    }

    override init(frame: CGRect) {
        println("init frame")
        super.init(frame: frame)
        setup()
    }

    required init(coder aDecoder: NSCoder) {
        println("init decoder")
        super.init(coder: aDecoder)
        setup()
    }

    func setup() {
        println("setup")
    }
}

然后我用下面的代码在我的 ViewController 中初始化

class ViewController: UIViewController {

    let bottomView = BottomView()

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        bottomView.frame = CGRectMake(0.0, self.view.frame.height/2.0, self.view.frame.width, self.view.frame.height/2.0)
        bottomView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleTopMargin
        self.view.addSubview(bottomView)

    }
}

我的输出是

init
init frame
setup
setup

所以我的问题是,为什么会调用 init(frame:) ?

【问题讨论】:

    标签: ios iphone ipad swift init


    【解决方案1】:

    super.init() 调用 self.init(frame:...)。本质上,这只是他们说frame 是可选的方式;如果你不通过它,他们会分配一个(0,0,0,0) 的框架。

    func init() {
      self.init(frame:CGRectMake(0,0,0,0));
    }
    

    【讨论】:

    • 好的,所以我已将 init 更改为方便的覆盖 init() 并调用 self.init(frame) 而不是 super.init。你知道是否有地方可以查看每个类的默认初始值设定项是什么?必须对 UITableView 做同样的事情,但默认是 init(frame: style:)
    • 你为什么要覆盖init()?看起来您只想将您的 setup 代码放入 init(frame:) 并让 init() 执行其默认操作。
    • 我认为 swift 需要具有一定的 init() 函数,即使覆盖其他函数也是如此。当我删除我的 override init() 函数时,我在 let bottomView = BottomView() 行上收到错误“Missing argument for parameter 'frame' in call”
    • 如果你想以这种方式实例化它,你必须重写init,因为子类不会直接继承它们的初始化器。我的意思是离开init,只打电话给super.init,别无其他。
    • 确定每个初始化器的用例;如果您发现您总是使用init 进行初始化,而从未使用init(frame) 进行初始化,请不要覆盖init(frame)。如果相反,请不要打扰覆盖init。如果您发现自己在不同的情况下同时使用这两种方法,请考虑让init 直接调用super.init,除非有特定的init--只有您不想在init(frame) 中采取的步骤。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 2022-12-07
    • 2015-11-06
    相关资源
    最近更新 更多