Swift类中的错误:属性未在super.init调用初始化 - 如何初始化需要在其初始化参数中使用self的属性 [英] Error in Swift class: Property not initialized at super.init call - How to initialize properties which need use of self in their initializer parameter

查看:4255
本文介绍了Swift类中的错误:属性未在super.init调用初始化 - 如何初始化需要在其初始化参数中使用self的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在swift中覆盖了一个 UITableViewController ,其中有两个必需的变量,它们通过使用 weak self 的引用,因为这些用于实现 UITableViewDataSource 协议,需要 self > class VideosListViewController:使用 tableView 属性



< UITableViewController {

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

// MARK: - 变量
var datasourceOnlineVideos:ASDataSource
var datasourceOfflineVideos:ASDataSource
}

现在的问题是它给我错误属性没有在超级初始化。 init调用,这是预期的解释如下: Swift类中的错误:属性未在super.init调用时初始化


Swift的编译器执行四有用的安全检查,以确保两阶段初始化完成没有错误



安全检查1指定的初始化程序必须确保其类所引入的所有属性



摘自:Apple Inc.Swift编程语言iBooks。 https://itunes.apple.com/us/book / swift-programming-language / id881256329?mt = 11


所以我的问题是:



如果swift类中的实例变量需要 self 引用要初始化为 ASDataSource 类型变量在这里,我该如何做



由于swift不允许我调用 super.init()在初始化所有的实例变量之前也不允许我在<$ c中的初始化器中使用 self 在调用 super.init()

之前,$ c> init()


目前我使用可选变量来解决问题。但为了学习目的,我想知道如何做到这一点。提前感谢:)

解决方案

您只需要在初始化器中颠倒顺序super.init / properties:

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

实例属性优先,那么可以调用超类初始化器。但这在你的情况下是不可能的,因为你引用 self



这种情况下的解决方法是属性隐式解包可选:

  var datasourceOnlineVideos:ASDataSource! 
var datasourceOfflineVideos:ASDataSource!

由于可选项不需要初始化,因此您可以在 super.init 方法。



此模式由Apple在几个类中使用,包括 UIViewController :当你从IB添加一个outlet,组件属性总是声明为隐式解包。这是因为控件本身不在初始化器中实例化,而是在稍后阶段。


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 :)

解决方案

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.

这篇关于Swift类中的错误:属性未在super.init调用初始化 - 如何初始化需要在其初始化参数中使用self的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆