Xcode对成员'init'的不明确引用

时间:2018-08-22 06:09:45

标签: ios swift xcode

我在Xcode 10 beta 3中使用了下面的代码,并且可以正常工作。然后将其移至Xcode 9以上传到iTunes Connect时,出现以下错误。下面也是代码。为什么它在Beta中有效,但在9中无效?

对成员'init'的不明确引用 1.存在“ init”的重载,其中包含部分匹配的参数列表:(Wrapped),(nilLiteral:())

error

 @objc func handleLongPressBuss(sender: UILongPressGestureRecognizer) {


    guard let index = ChannelText.index(where: { $0 == sender.view }) else { assertionFailure(); return }

    let buslist = "\(sharedData.ChannelBuss[index])"
    let M = "M"
    let A = "A"
    let B = "B"

    let busViewController = BusViewController.instantiate()
    busViewController.modalPresentationStyle = .popover
    busViewController.popoverPresentationController?.sourceView = ChannelText[index]

    busViewController.state = .init(
        isMOn: buslist.contains(M),
        isAOn: buslist.contains(A),
        isBOn: buslist.contains(B),
        index: index,
        channelTitle: ("\(sharedData.ChannelLabel[index])")
    )

    present(busViewController, animated: true)

}

这是总线控制器

import UIKit

final class BusViewController: UIViewController {

func makeBusRequestOn(bus: String, inputNumber: Int) -> NSMutableURLRequest
{
    print()
    return NSMutableURLRequest(url: URL(string: "\(baserequest)AudioBusOn&Value=\(bus)&Input=\(inputNumber)" )!)

}
func makeBusRequestOff(bus: String, inputNumber: Int) -> NSMutableURLRequest
{
    print()
    return NSMutableURLRequest(url: URL(string: "\(baserequest)AudioBusOff&Value=\(bus)&Input=\(inputNumber)" )!)

}

struct State {
    var isMOn: Bool
    var isAOn: Bool
    var isBOn: Bool
    var index: Int
    var channelTitle: String

}
var state: State!


static func instantiate() -> BusViewController {
    return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BusViewController") as! BusViewController
}
@IBAction func masterChanged(_ sender: UISwitch) {

    print(sender.isOn)
    let requestURL: NSMutableURLRequest
    if sender.isOn {
        requestURL = makeBusRequestOn(bus: "M", inputNumber: state.index + 1 )
    }
    else {
        requestURL = makeBusRequestOff(bus: "M", inputNumber: state.index + 1 )
    }

    httpGet2(requestURL as URLRequest?) { string, error in
        guard error == nil && string != nil else {
            print(error?.localizedDescription ?? 777)
            return
        }
        print(string!)
    }
}

@IBAction func busAChanged(_ sender: UISwitch) {
    print(sender.isOn)
    let requestURL: NSMutableURLRequest
    if sender.isOn {
        requestURL = makeBusRequestOn(bus: "A", inputNumber: state.index + 1 )
    }
    else {
        requestURL = makeBusRequestOff(bus: "A", inputNumber: state.index + 1 )
    }

    httpGet2(requestURL as URLRequest?) { string, error in
        guard error == nil && string != nil else {
            print(error?.localizedDescription ?? 777)
            return
        }
        print(string!)
    }
}
@IBAction func busBChanged(_ sender: UISwitch) {
    print(sender.isOn)
    let requestURL: NSMutableURLRequest
    if sender.isOn {
        requestURL = makeBusRequestOn(bus: "B", inputNumber: state.index + 1 )
    }
    else {
        requestURL = makeBusRequestOff(bus: "B", inputNumber: state.index + 1 )
    }

    httpGet2(requestURL as URLRequest?) { string, error in
        guard error == nil && string != nil else {
            print(error?.localizedDescription ?? 777)
            return
        }
        print(string!)
    }
}
@IBOutlet var channelLabel: UILabel!
@IBOutlet var masterLabel: UILabel!
@IBOutlet var masterSwitch: UISwitch!

@IBOutlet var busALabel: UILabel!
@IBOutlet var busASwitch: UISwitch!

@IBOutlet var busBLabel: UILabel!
@IBOutlet var busBSwitch: UISwitch!

override func viewDidLoad() {
    super.viewDidLoad()
    updateUI()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let size = view.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
    preferredContentSize = CGSize(width: size.width + 30, height: size.height)


}

func updateUI() {
    masterSwitch.isOn = state.isMOn
    busASwitch.isOn = state.isAOn
    busBSwitch.isOn = state.isBOn
    channelLabel.text = state.channelTitle
}


@IBAction func okTapped() {
    dismiss(animated: true)

}
}

2 个答案:

答案 0 :(得分:0)

在这种情况下,您不能使用简写.init(...),因为state的类型是State!,也就是ImplicitlyUnwrappedOptional<State>ImplicitlyUnwrappedOptional没有要使用的State初始化程序。

一个简单的例子可以用来说明这一点:

var s: String = .init() // OK
var s: String! = .init() // Fails

但是您不能简单地删除可选类型,因为这样您的控制器需要一个初始化程序来初始化state。因此,我认为解决此问题的最佳方法是将其写为类型名称:State(...)

答案 1 :(得分:0)

使用Xcode 9.4.1中的简化代码进行测试,然后进行编译。

class BusViewController {
    var state: State? //<- Not "Implicitly Unwrapped"
    //...
}

let busViewController = BusViewController()

busViewController.state = .init(
    isMOn: true,
    isAOn: true,
    isBOn: true,
    index: 0,
    channelTitle: ""
)

即使在Xcode 9中,点引号表示法的似乎类型推断也足以(通常)Optional聪明地工作。

您的代码在Xcode 10 beta中进行编译的原因之一与此有关:

Reimplementation of Implicitly Unwrapped Optionals

隐式解包的Optional的整个重新实现已在Xcode 10中完成,因此隐式解包的Optional的行为与Optional相同。


但是,我不建议您为State!使用隐式解包的可选state,因为在给出非nil值之前可以访问它。您最好将其声明为通常的可选State?,然后以访问访问state的可选安全方式重写代码。

在Swift中,URLRequestNSMutableURLRequest更有用。