【问题标题】:super init isn't called on all paths before returning from initializer在从初始化程序返回之前,不会在所有路径上调用 super init
【发布时间】: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相关的东西?

标签: ios swift


【解决方案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")
    }
    

    它对我有用。

    【讨论】:

      猜你喜欢
      • 2020-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      • 2015-09-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-22
      相关资源
      最近更新 更多