如何在闭包中访问类的变量?



我读过这个主题:Swift访问闭包中的类变量。但对我没有帮助。

问题

我有一个ViewControllerData来显示数据,其他ViewControllerEdit来编辑数据。我想把对象从ViewControllerData发送到ViewControllerEdit,我用performSegue做这个,但我不能从ViewControllerEdit得到编辑过的对象。我想在prepare函数中传递类似闭包(funcReturnFromEdit(的参数。

class ViewControllerData: UIViewController, UITableViewDataSource, UITableViewDelegate {
    @IBOutlet weak var tableViewData: UITableView!
    var saleOrder : SaleOrder?  // THIS! <--------
    // In this closure I want take the edited object.
    let funcReturnFromEdit = { (saleEdited : SaleOrder) -> () in
        self.saleOrder = saleEdited // I can't do this. Error: Value of type '(ViewControllerData) -> () -> (ViewControllerData)' has no member 'saleOrder'
    }
    ....
      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        segue.identifier == "segueEditOrder" {
        let editVc = segue.destination as! ViewControllerEdit
        if saleOrder != nil {
            editVc.saleOrderToEdit = saleOrder!.copy() as! SaleOrder
        }
        editVc.funcReturn = self.funcReturnFromEdit // <-- Not works
    }
}

错误为:Instance member 'saleOrder' cannot be used on type 'ViewControllerData '

除此之外,我不知道如何在ViewControllerEdit 上创建此函数

class ViewControllerEdit: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var saleOrderToEdit : SaleOrder?
    var funcReturn = { (SaleOrder) -> Void in {} } // <- This not compile. How to do this?
    ...
    /*
     Funcs to make edition...
    */
    func endEditions() {
        funcReturn(saleOrderToEdit) // <- Here I want send to back ViewControllerData
    }
}

如果您需要在闭包中使用全局变量/方法,请将self.放在变量/方法之前

所以你可以更换这个

saleOrder = saleEdited

带有

self.saleOrder = saleEdited

但问题似乎也在其他地方。您只需要将saleOrder从第一个ViewController传递到第二个ViewController,在那里您可以编辑它,然后将数据传递回第一个ViewController

因此,首先从ViewControllerData中删除不必要的代码:

let funcReturnFromEdit = { (saleEdited : SaleOrder) -> () in
    saleOrder = saleEdited // I can't do this. 
}

并修复ViewControllerEdit中的完成处理程序以替换

var funcReturn = { (SaleOrder) -> Void in {} }

带有

var funcReturn : ((SaleOrder) -> ())?

还要编辑endEditions方法,因为funcReturn是可选的

func endEditions() {
    funcReturn?(saleOrderToEdit)
}

现在,只需在ViewControllerData中修复prepare方法,即可设置用户从ViewControllerEdit 调用funcReturn时应执行的操作

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segueEditOrder" {
        let editVc = segue.destination as! ViewControllerEdit
        if let saleOrderToPass = saleOrder {
            editVc.saleOrderToEdit = saleOrderToPass
            editVc.funcReturn = { saleEdited in
                self.saleOrder = saleEdited //This code is executed when you call funcReturn?(saleOrderToEdit) from ViewControllerEdit
            }
        }
    }
}

您必须在ViewControllerEdit中声明一个完成闭包,并在endEditions 中调用它

class ViewControllerEdit: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var saleOrderToEdit : SaleOrder!
    var editCompletion : ((SaleOrder)->())?
...
    func endEditions() {
        editCompletion?(saleOrderToEdit)
    }

ViewControllerData prepare(for中分配闭包

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segueEditOrder" {
        let editVc = segue.destination as! ViewControllerEdit
        if let saleOrderToEdit = saleOrder {
            editVc.saleOrderToEdit = saleOrderToEdit
            editVc.editCompletion = { [weak self] saleEdited in 
                self?.saleOrder = saleEdited
            }
        }
    }
}

出于安全原因,如果saleOrdernil ,我建议也实施shouldPerformSegue来抑制segue

func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    return saleOrderToEdit != nil
}

注意:请不要在Swift 中使用丑陋的objective-c-ishcopy()

最新更新