首页 > 解决方案 > Xcode 对成员“init”的模糊引用

问题描述

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

对成员 'init' 的模糊引用 1. 这些部分匹配的参数列表存在对 'init' 的重载:(Wrapped), (nilLiteral: ())

错误

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

}
}

标签: iosswiftxcode

解决方案


使用 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: ""
)

Optional即使在 Xcode 9 中,点前导符号的类型推断似乎也足够聪明(通常) 。

您的代码在 Xcode 10 beta 中编译的一个原因可能与此有关:

隐式解包选项的重新实现

在 Xcode 10 中已完成对 Implicitly Unwrapped Optional 的重新实现,因此隐式展开 Optional 的行为与 (通常) 相同Optional


但我不建议您使用隐式展开的 Optional State!for state,因为它可能在给出非 nil 值之前被访问。你最好像往常一样声明它 OptionalState?并将你的代码重写为你访问的 Optional-safe 方式state

URLRequestNSMutableURLRequest在 Swift 中更好用的一种。


推荐阅读