在从初始化程序返回之前,不会在所有路径上调用 super init

Posted

技术标签:

【中文标题】在从初始化程序返回之前,不会在所有路径上调用 super init【英文标题】:super init isn't called on all paths before returning from initializer 【发布时间】:2016-12-06 14:05:34 【问题描述】:

我做了一个封装 Alamofire 的框架。

在我的框架中测试时(在测试目标中)我有这个代码可以正常工作。

import Foundation
@testable import NetworkManager

class MockRouter: Router 


enum APICalls 
    case func1
    case func2


var calls: APICalls!

init(calls: APICalls) 
    self.calls = calls



当我将它作为框架添加到不同的项目时

import Foundation
import NetworkManager

class JokesRouter: Router 

enum APICalls 
    case func1
    case func2


var calls: APICalls!

init(calls: APICalls) 
    self.calls = calls




我得到一个错误:

在从初始化程序返回之前,不会在所有路径上调用超级初始化

所以我添加了 Super.init()

init(calls: APICalls) 
    super.init()
    self.calls = calls

现在我得到了这个错误:

super.init 不能在初始化程序之外调用

知道是什么问题吗?

【问题讨论】:

请显示Router 实现(初始化程序)。 路由器中没有初始化 那就是问题所在。您需要一些公共初始化程序才能调用子类。 那么为什么它对测试目标有效? 与bugs.swift.org/browse/SR-2295相关的东西? 【参考方案1】:

您需要在Router 中声明一个空的public init()

虽然这是一个神秘的错误,但问题是子类无法调用super.init(),因为除非您将其声明为public,否则无法在NetworkManager 模块之外访问该初始化程序。 Router中自动生成的init()默认不是public

它在您的测试类中有效,因为 @testable import 回避了默认的 internal 访问限制。

【讨论】:

【参考方案2】:

我正在尝试创建 Swift 编程的继承功能。

我将ViewController 创建为超类。 然后我创建了另一个类作为超类ViewControllerViewControllerA的子类名称

ViewController 类:

import UIKit

class ViewController: UIViewController 

  //: public variables
  var area:               CGFloat?


  override func viewDidLoad() 
      super.viewDidLoad()
      // Do any additional setup after loading the view, typically from a nib.
  

  override func didReceiveMemoryWarning() 
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
  

  public func printArea()
      print("Print area in Super class")
  

  public func calculateArea()

  


ViewControllerA 作为子类:

import UIKit

class ViewControllerA: ViewController 

    var length:                 CGFloat?


     init( len: CGFloat) 
        self.length = len
        super.init(nibName: nil, bundle: nil)
    

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

    override func printArea() 
        print("The are of A \(area!)")
    


    override func calculateArea() 
        area = length! * length!
    

我得到了错误。 Must call a designated initializer of the superclass 'ViewController' 在子类的 init 方法中。

所以我在超类中声明了空的init 方法,即ViewController

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) 
    super.init(nibName: nil, bundle: nil)


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

它对我有用。

【讨论】:

以上是关于在从初始化程序返回之前,不会在所有路径上调用 super init的主要内容,如果未能解决你的问题,请参考以下文章

CoreData 和 Codable 类编译器错误:在从初始化程序返回之前,未在所有路径上调用“self.init”

在从初始化程序返回之前不调用 Super.init

从初始化程序返回之前不会调用Super.init

如何确保在从 Mongoose 中的函数返回之前执行异步调用?

json.swift 错误是 Self.init 在委托初始化程序中的所有路径上都没有调用

如何在从 Meteor.method 返回之前等待子流程结果