Swift-在协议/委托之间传递数据时出错(发现为零)

Swift-在协议/委托之间传递数据时出错(发现为零),swift,null,delegates,protocols,Swift,Null,Delegates,Protocols,我正在用swift 3.0开发一个应用程序。我想做的是,从“MainMapVC”类,这是一个视图,其中有一个带有日期滑块的地图(请参见附件)。我想移动滑块并将滑块位置(1、2或3)发送到LeftSideViewController,它是根据所选日期更新内容的侧视图(图例) MainMapVC的视图: import UIKit protocol MainMapVCDelegate: class { func moveSliderDates(datePos: Int) } clas

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

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

}

}
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()
}
 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)

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

带有图例的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))      

}

}
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()
}
 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)

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

现在我必须在两个视图控制器之间传递一个值。但问题是,我得到了错误“致命错误:在展开可选值时意外发现nil”。基本上我有一个“零”代表

weak var delegate: LeftSideDelegate? = nil
但是,请不要找到错误所在,因为委托的定义类似于“var delegate:mainmapvcdegate!”,我在“MainMapVC”类中将其称为“delegate.moveSliderDates(datePos:Int(roundedValue))”

有人知道我在代表发言中失败的地方吗?谢谢:)

我附加了这两个类的代码,以便您看到整个代码

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

}

}
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()
}
 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)

}
    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)
}
moveSliderDates函数中的委托值为“nil”:

delegate?.moveSliderDates(datePos: Int(roundedValue))
类LeftSideViewController(第一种方式):

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

}

}
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()
}
 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)

}
    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)
}
由于“MainVC”的委托为“nil”,因此不能进入此函数内部:

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

}

}
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()
}
 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)

}
    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)
}
Class 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))      

}

}
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()
}
 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)

}
    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)
}
类LeftSideViewController(第二种方式):

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

}

}
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()
}
 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)

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

从不进入函数列表功能

您会收到错误,因为您通过以下代码将委托定义为强制展开noy nil版本
var delegate:LeftSideDelegate

相反,你需要像这样改变它。您不应该为代理创建强引用循环

weak var delegate: LeftSideDelegate? = nil
然后,对所有委托调用执行包装版本委托调用

delegate?.changeZindexDelivery()
除此之外,将行
protocolleftsidedelegate{
更改为
protocolleftsidedelegate:class{

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

首先,在要将数据传递给另一个视图控制器的类中,以这种方式声明协议

protocol SampleDelegate: class {
    func delegateFunctionCall(data: String)
}
然后,使用弱变量类型将委托变量创建为可选变量。若要传递数据或触发操作,请使用调用委托方法

class SecondViewController: UIViewController {

    weak var delegate: SampleDelegate? = nil

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

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

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
    }
}
使用通知在视图控制器之间传递数据

在目标视图控制器中,注册准备好调用的处理程序函数。您可以在视图加载中添加此注册代码

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   
    }
}
然后在另一个视图控制器中,如果要传递数据,只需调用

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

@JordiGallenRenau您正在分机中接收此协议调用,对吗?(
extension MainMapVC:LeftSideDelegate
)在里面放一个断点,看看它是否被调用。顺便说一句,你说你不能调用moveSliderDates函数是什么意思?这会给你带来一些错误?@jordigallenreneu哦,所以你需要为你的主视图控制器准备一个segue方法。目标必须是你的左视图控制器。然后你需要执行destinationViewController.delegate=self@JordiGallenRenau您仍然无法使其工作吗?您没有使用segue吗?您希望从main到left传递数据,因此您需要的是,在您的left view控制器上定义协议,创建委托变量并对其调用方法。然后在您的maincontroller上,将main本身设置为left view控制器的委托对象呃,我被你的观点弄糊涂了code@JordiGallenRenau我已经更新了两种在视图控制器之间传递数据的正常方式。如果这有帮助,请将其标记为正确答案。如果仍然不正确,请告诉我work@JordiGallenRenau当目标视图控制器运行时,是否尝试调用委托方法尚未初始化?这两种方法仅在源视图控制器和目标视图控制器有效时才起作用