我在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)
}
}
答案 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中,URLRequest
比NSMutableURLRequest
更有用。