Swift-在协议/委托之间传递数据时出错(发现为零) [英] Swift - Error passing data between protocols / delegates (found nil)

查看:100
本文介绍了Swift-在协议/委托之间传递数据时出错(发现为零)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发带有Swift 3.0的应用程序。我想做的是在 MainMapVC类中,该视图是您具有带日期滑块的地图的视图(请参见附件图像)。我想移动滑块并将该滑块位置(1、2或3)发送到LeftSideViewController,这是侧视图(图例),它根据所选日期更新内容。

I am developing an application with swift 3.0. Where what I want to do is, from the "MainMapVC" class, which is the view where you have a map with a date slider (see the attached image). I want to move the slider and send that slider position (1,2 or 3) to LeftSideViewController which is the side view (the legend) updating the content depending on the selected date.

MainMapVC的视图:

带图例的MainMapVC视图:

好,我已经到了必须在两个视图控制器之间传递值的地步。但是问题是我收到错误严重错误:在展开可选值时意外发现nil。基本上我有一个零委托。

Well, and I've come to the point where I have to pass a value between the two view controllers. But problem is that I get the error "fatal error: unexpectedly found nil while unwrapping an optional value". Basically I have a "nil" delegate.

但是找不到错误在哪里,因为委托的定义就像 var委托:MainMapVCDelegate!。我在 MainMapVC类中将其称为 delegate.moveSliderDates(datePos:Int(roundedValue))。

But do not find where the error is, because the definition of the delegate is like "var delegate: MainMapVCDelegate!" And I call it "delegate.moveSliderDates (datePos: Int (roundedValue))" in the "MainMapVC" class.

有人知道我在代表声明中的失败之处吗?谢谢:)

我附上了两个类的代码,以便您可以看到完整的代码。

I attach the code of the two classes so that you see the whole code.

MainMapVC类(第一种方法):

import UIKit

protocol MainMapVCDelegate: class {

    func moveSliderDates(datePos: Int)

}


class MainMapVC: UIViewController, UISearchBarDelegate, CLLocationManagerDelegate, GMSMapViewDelegate {

//MARK: VARIABLES
weak var delegate: MainMapVCDelegate? = nil


let step: Float = 1
@IBAction func moveSliderDates(_ sender: UISlider) {
    let roundedValue = round(sender.value / step) * step
    sender.value = roundedValue 
    delegate?.moveSliderDates(datePos: Int(roundedValue))      

}

}

moveSliderDates函数内部的委托值为 nil:

delegate?.moveSliderDates(datePos: Int(roundedValue))

LeftSideViewController类(第一种方式):

import UIKit

class LeftSideViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, customCellDelegate, MainMapVCDelegate {

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "MainMapVC" {
        let secondViewController = segue.destination as! MainMapVC
        secondViewController.delegate = self
    }
}

func moveSliderDates(datePos: Int){
    print(datePos)
    print("/////////////")
    tableSideLeft.reloadData()
}

由于 MainVC的委托为 nil,因此未在此函数内输入:

类MainMapVC(第二种方式):

 let step: Float = 1
 @IBAction func moveSliderDates(_ sender: UISlider) {
    let roundedValue = round(sender.value / step) * step
    sender.value = roundedValue

    let data:[String: Int] = ["data": Int(roundedValue)]
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: data)

}

Class LeftSideViewController(第二种方式):

    func listnerFunction(_ notification: NSNotification) {
    if let data = notification.userInfo?["data"] as? String {
        print(data)
    }



override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(listnerFunction(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)
}

从不进入函数列表功能

推荐答案

您会收到此错误,因为通过以下代码将您的委托定义为强制展开的无零版本: var委托:LeftSideDelegate!

You get the error because you defined your delegate as force unwrapped noy-nil version by this code var delegate: LeftSideDelegate!

相反,您需要像这样更改它。

Instead, you need to change it like this. You should not create strong reference cycle for delegate.

weak var delegate: LeftSideDelegate? = nil

然后为所有委托调用,进行包装版本的委托调用

Then for all your delegate calles, do the wrapped version delegate call

delegate?.changeZindexDelivery()

除此之外,将您的行 protocol LeftSideDelegate {更改为 protocol LeftSideDelegate:class {

Other than that, change your line protocol LeftSideDelegate { into protocol LeftSideDelegate : class {

使用委托在视图控制器之间传递数据

首先,在您要传递数据发送到另一个视图控制器,以这种方式声明协议

First, in the class where you want to pass the data to another view controller, declare protocol in this way

protocol SampleDelegate: class {
    func delegateFunctionCall(data: String)
}

然后,创建弱变量类型的委托变量。要传递数据或触发操作时调用委托方法

Then, create delegate variable as optional with type weak var. Call delegate method with you want to pass data or trigger action

class SecondViewController: UIViewController {

    weak var delegate: SampleDelegate? = nil

    @IBAction func sendTextBackButton(sender: AnyObject) {
        delegate?.delegateFunctionCall(data: textField.text!)

    }
}

最后,在您要接收动作或数据的视图控制器中,实现协议。当您启动第二个视图控制器时,将其委托变量设置为当前视图控制器

Finally in your view controller that you want to receive action or data, implement the protocol. When you are initiating the second view controller, set it's delegate variable to be the current view controller

class FirstViewController: UIViewController, SampleDelegate {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showSecondViewController" {
            let secondViewController = segue.destination as! SecondViewController
            secondViewController.delegate = self
        }
    }

    func delegateFunctionCall(data: String) {
        label.text = data
    }
}

使用通知在视图控制器之间传递数据

在目标视图控制器中,注册一个随时可以调用的处理函数。您可以在加载后查看此注册代码

In the destination view controller, register a handler function that is ready to be called. You can add this registration code in view did load

NotificationCenter.default.addObserver(self, selector: #selector(listnerFunction(_:)), name: NSNotification.Name(rawValue: "notificationName"), object: nil)

func listnerFunction(_ notification: NSNotification) {
    if let data = notification.userInfo?["data"] as? String {
        // do something with your data   
    }
}

然后在另一个视图控制器中,如果要传递数据,只需调用

Then in another view controller, if you want to pass data, simply call this

let data:[String: String] = ["data": "YourData"]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notificationName"), object: nil, userInfo: data) 

这篇关于Swift-在协议/委托之间传递数据时出错(发现为零)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆