Swift segues 紧密耦合吗?

Are Swift segues closely coupled?

在Swift中使用MVC转发数据的常用方法是使用prepare(for:sender:)。在该方法中,您可以获得对目标 VC 的引用并访问其属性以发送数据。但这不是考虑耦合视图控制器吗?我希望答案不被视为意见问题,因为我真的很想了解 segues 如何适合 MVC.

segue 中传递数据与 MVC 完全兼容。 destinationVC 被认为是 sourceVC 的 View。当控制器与 View 通信时,它会使用所需的数据配置 View。写入 destinationVC 的 public 接口(属性)就是你设置它的方式。这就是 prepare(for segue:sender).

中发生的事情

耦合的关注与重用有关。 viewController 耦合得越紧密,重用它们就越困难。如果 destinationVC 知道 sourceVC 的详细信息,这只是一个问题。如果 destinationVC 需要将数据传回 sourceVC,它应该使用 delegation(其中 protocol用于定义 sourceVC 实现的方法。

如果视图控制器 A 转至视图控制器 B 并假定它是类型 ViewControllerB 那么是的,那就是紧耦合:

prepare(for: segue, sender: sender) {
   if let viewControllerB = segue.destination as? ViewControllerB {
      viewControllerB.property = value
   }
}

该代码仅在目标为特定 class、ViewControllerB 且第一个视图控制器必须知道 ViewControllerB.

的属性时才有效

这通常不是问题,因为通常当您转到另一个视图控制器时,您知道您要求什么,因此知道会发生什么。

但是,您可以使用相同的 prepare(for:sender:) 方法来切换到具有共同属性的几种不同类型的视图控制器中的任何一种。

在这种情况下,您可以使用协议使耦合更松散:

方法 2:使用协议松散耦合

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
}

然后在第一个view controller的prepare(for:sender:):

prepare(for: segue, sender: sender) {
   if let destination = segue.destination as? DestProtocol {
      destination.property = value
   }
}

使用第二种方法,第一个视图控制器的 prepare(for:sender) 不知道目标是 ViewControllerB 的一个实例。它只是检查目标是否符合 DestProtocol。 segue 可能正在加载 ViewControllerBViewControllerC.

的实例