Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在委托方法内调用IBOutlet变量时获取错误_Ios_Swift_Xcode_Delegates - Fatal编程技术网

Ios 在委托方法内调用IBOutlet变量时获取错误

Ios 在委托方法内调用IBOutlet变量时获取错误,ios,swift,xcode,delegates,Ios,Swift,Xcode,Delegates,我已经为我的picker视图创建了一个额外的类。当我按下一个按钮和一个普通按钮时,会显示一个PickerView。这个很好用。 我希望当我选择一个项目时,按钮的标题会改变 我和一位代表一起尝试 在我的picker类中,我创建了一个协议: protocol CodeDelegate { func getCode(code: String) } class Picker: UIPickerView { var codeDelegate: CodeDelegate? func

我已经为我的picker视图创建了一个额外的类。当我按下一个按钮和一个普通按钮时,会显示一个PickerView。这个很好用。 我希望当我选择一个项目时,按钮的标题会改变

我和一位代表一起尝试

在我的picker类中,我创建了一个协议:

protocol CodeDelegate {
    func getCode(code: String)
}

class Picker: UIPickerView {

    var codeDelegate: CodeDelegate?

  func setupPickerViewForRegion(view: UIView, barButtonItem: UIBarButtonItem) {
        codeDelegate = HomeViewController()
        
        barButtonRegion = barButtonItem
        
        viewFromController = view
        createToolbar()
        closeWhenTapOnScreen()
        
        UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.addSubview(blurScreenView)
        
        view.addSubview(textField)
        textField.inputView = pickerView
        textField.becomeFirstResponder()
    }

.
.
.
.
}

extension Picker: UIPickerViewDelegate {

.
.
.

 func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    
        let regionCode = regions[row].prefix(2)
            
        codeDelegate!.getCode(code: String(regionCode))

    }
}
选择值后,将执行委托

我已经让我的另一个班级遵守了协议

class HomeViewController: UIViewController, CodeDelegate {

    @IBOutlet weak var pickRegion: UIBarButtonItem!

func getCode(code: String) {
        pickRegion.title = code
    }
}
在委托方法中,我想将传递的字符串分配给按钮。但是,我在那里得到了一个错误:

Projekt[7585:218750]致命错误:在执行时意外发现零 隐式展开可选值:file Projekt/HomeViewController.swift,第270行


我所有的插座都仍然连接,所以为什么会抛出此错误?

您的代码有两个不同的问题

首先,使用代码
codeDelegate=HomeViewController()设置选择器的委托。表达式HomeViewController()
创建一个新的空HomeViewController实例,该实例与屏幕上的任何内容无关。创建这样的视图控制器不允许它从其storyboard/XIB文件加载视图,因此它的输出将为零。这为崩溃做好了准备,因为当调用委托方法时,视图控制器将尝试调用为零的出口。您应该从HomeViewController设置代理

如下所示:

let picker = Picker() 
picker.delegate = self

代码的第二个问题是一个非常坏的习惯。行
codeDelegate!。如果
codeDelegate
为nil,则getCode(code:String(regionCode))
将崩溃。(
是“强制展开”操作符,也称为“如果为零则崩溃”操作符。)您应该改为使用
codeDelegate?.getCode(code:String(regionCode))
(将
更改为
)这不太可能是导致崩溃的原因,但使用optionals仍然是一件非常糟糕的事情。

哦,是的,我明白了。这是我自己犯的一个可怕的错误。我在HomeViewController中设置了代理,现在它工作正常。非常感谢。通过调用视图控制器的初始值设定项(例如直接
ViewControllerClass()
)来创建视图控制器几乎总是错误的。唯一一次不是这样的情况是视图控制器在代码中创建其视图层次结构,而不是从序列图像板或XIB文件中加载。