【问题标题】:How to declare a variable with two possible types如何声明具有两种可能类型的变量
【发布时间】:2018-11-23 13:57:59
【问题描述】:

我有两个Core Data entities,它们用两个部分填充一个UITableView,每个部分一个实体。当用户点击表格行时,他们会被定向到发送该行数据的另一个视图。目前是这样实现的:

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

        if send_array_inc.isEmpty {
            secondViewController.send_array_exp = send_array_exp
        } else if send_array_exp.isEmpty {
            secondViewController.send_array_inc = send_array_inc
        }
    }
}

问题:

由于有两个实体,因此发送到下一个视图的数据有两种可能的类型(IncomeExpenses)。如何在具有一个变量的下一个视图中使用该数据?我在ViewDidLoad 中执行以下操作,但send_array 的范围仍在该函数内。我怎样才能让send_array 在外面可用?

if send_array_inc.isEmpty {
     var send_array = [Expenses]()
     send_array = send_array_exp
} else if send_array_exp.isEmpty {
     var send_array = [Income]()
     send_array = send_array_inc
}

理想情况下,我希望这样做不为每个实体创建单独的视图结果,但如果另一种解决方案更好和更现实,我愿意重构。谢谢

【问题讨论】:

  • 考虑只使用一个实体并添加一个类型列来区分费用和收入。另一个要考虑的选择是在 Core Data 中使用继承,并在父实体的视图控制器中定义要编辑的公共字段。
  • 我真的很喜欢迈克的第一个想法,谢谢!

标签: swift uitableview core-data scope


【解决方案1】:

使您的两种类型的数据对象符合共享协议。使目标视图控制器的send_array 成为符合该协议的对象。

在您的 EditValuesViewController 的代码中,询问 send_array 以确定传入的数据对象类型。

编辑:

定义协议

@protocol dataArrayProtocol {
  var dataArray: Array
}

定义 2 个符合该协议的结构

struct ExpensesArrayStruct: dataArrayProtocol {
  var dataArray: [Expenses]
}

struct IncomeArrayStruct: dataArrayProtocol {
  var dataArray: [Income]
}

为您的EditValuesViewController 提供符合该协议的属性 类 EditValuesViewController: UIViewController { var dataArrayStruct: dataArrayProtocol }

还有你的prepare(for:sender) 方法

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

        if send_array_inc.isEmpty {
            secondViewController.dataArrayStruct = ExpensesArrayStruct(dataArray: send_array_exp)
        } else if send_array_exp.isEmpty {
            secondViewController.dataArrayStruct = IncomeArrayStruct(dataArray: send_array_inc)
        }
    }
}

以及处理数据:

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)
  if let expensesStruct = dataArrayStruct as? ExpensesArrayStruct {
     //deal with expenses array
  } else if let incomeStruct = dataArrayStruct as? IncomeArrayStruct {
     //deal with income array
  }
}

请注意,我在 SO 编辑器中敲出了这段代码,并没有尝试编译它。我可能犯了一些小错误。不过它应该会给你这个想法。

【讨论】:

  • 很难让像数组这样的通用集合符合共享协议。您可以将数组包装在结构中并使结构符合您的协议。
猜你喜欢
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2012-06-26
  • 2020-07-13
  • 1970-01-01
  • 2020-10-13
  • 1970-01-01
相关资源
最近更新 更多