Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

ios - Error in Swift class: Property not initialized at super.init call - How to initialize properties which need use of self in their initializer parameter

I am overriding a UITableViewController in swift, in which I have two required variables which are initialized by using a weak reference of self since these are used to implement UITableViewDataSource protocol and need self reference to use its tableView property

class VideosListViewController: UITableViewController {
  
  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.datasourceOfflineVideos = ASDataSource(tableViewController: self)
    self.datasourceOnlineVideos = ASDataSource(tableViewController: self)
  }
  
  // MARK: - Variables
  var datasourceOnlineVideos:ASDataSource
  var datasourceOfflineVideos:ASDataSource
  }

Now the problem is as it is giving me error Property not initialized at super.init call which is expected as explained here: Error in Swift class: Property not initialized at super.init call.

Swift’s compiler performs four helpful safety-checks to make sure that two-phase initialization is completed without error

Safety check 1 A designated initializer must ensure that all of the “properties introduced by its class are initialized before it delegates up to a superclass initializer.

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11

So my question is:

If an instance variable in swift class needs self reference to be initialized like ASDataSource type variables here, how can I do that??

Since swift doesn't allow me call the super.init() before initiazing all the instance variables And also doesn't allow me to user self within the initializer in the init() before calling super.init()

Currently I am using optional variable(s) to resolve the issue. But for learning purpose I want to know how to do that. Thanks in advance :)

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

You just have to invert the order super.init/properties in your initializer:

 required init(coder aDecoder: NSCoder) {
    self.datasourceOfflineVideos = ASDataSource(tableViewController: self)
    self.datasourceOnlineVideos = ASDataSource(tableViewController: self)
    super.init(coder: aDecoder)
  }

instance properties comes first, then the superclass initializer can be invoked. But that's not possible in your case, because you are referencing self.

The workaround in this case is to make the properties implicitly unwrapped optionals:

var datasourceOnlineVideos:ASDataSource!
var datasourceOfflineVideos:ASDataSource!

Since optionals don't need to be initialized, you can safely initialize them after the super.init method has been called. Being implicitly unwrapped, you use them as any other non optional property.

This pattern is used by Apple in several classes, including UIViewController: when you add an outlet from IB, the component property is always declared as implicitly unwrapped. That's because the control itself is not instantiated in the initializer, but at a later stage.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...