在使用MVC的Swift中,向前发送数据的常用方法是使用prepare(for:sender:)
。在该方法中,您将获得对目标VC的引用并访问其属性以发送数据。但是,是不是认为耦合视图控制器?我希望这个答案不被认为是一个意见问题,因为我真的很想了解segv如何适应MVC。
答案 0 :(得分:5)
在 segue 中传递数据与MVC完全兼容。 destinationVC被视为sourceVC的 View 。当控制器与 View 通信时,它会使用所需的数据配置 View 。写入目标VC的公共接口(属性)是您如何设置它。这就是prepare(for segue:sender)
中发生的事情。
对耦合的关注与重用有关。 viewControllers的耦合越紧密,重用它们就越困难。如果destinationVC
知道sourceVC
的详细信息,则这只是一个问题。如果destinationVC
需要将数据传回sourceVC
,则应使用委派(其中协议用于定义方法) sourceVC 实现)。
答案 1 :(得分:2)
如果视图控制器A分段查看控制器B并假设它是ViewControllerB
类型,那么是,那就是紧耦合:
prepare(for: segue, sender: sender) {
if let viewControllerB = segue.destination as? ViewControllerB {
viewControllerB.property = value
}
}
该代码仅在目标是特定类ViewControllerB
时才有效,并且第一个视图控制器必须知道ViewControllerB
的属性。
这通常不是问题,因为通常当你转向另一个视图控制器时,你知道你所要求的是什么,因此会发生什么。
但是,您可以使用相同的prepare(for:sender:)
方法来转换为具有共同属性的几种不同类型的视图控制器中的任何一种。
在这种情况下,您可以使用协议使耦合更松散:
protocol DestProtocol {
var property: String
}
您的ViewControllerB
可能符合DestProtocol
class ViewControllerB: UIViewController, DestProtocol {
var property: string
//The rest of ViewControllerB
}
您可能还的ViewControllerC
符合DestProtocol
class ViewControllerC: UIViewController, DestProtocol {
var property: string
//The rest of ViewControllerC
}
然后在第一个视图控制器中prepare(for:sender:)
:
prepare(for: segue, sender: sender) {
if let destination = segue.destination as? DestProtocol {
destination.property = value
}
}
使用第二种方法,第一个视图控制器prepare(for:sender)
不知道目标是ViewControllerB
的实例。它只是检查目的地是否符合DestProtocol
。 segue可能正在加载ViewControllerB
或ViewControllerC
的实例。