【问题标题】:Pass array by reference between viewcontrollers in swift快速在视图控制器之间通过引用传递数组
【发布时间】:2015-08-17 11:27:08
【问题描述】:

在使用 Objective-C 时,我只需在 VC_B 中分配一个属性,即可将 NSMutableArray 从一个视图控制器 VC_A 传递给另一个 VC_B

VC_B.list = self.list

self 是 VC_A

当视图控制器从导航堆栈中弹出时,它允许在VC_A 的列表中看到列表中VC_B 中所做的更改。

然而,在 Swift 中,由于数组是按值传递的,因此上述分配不起作用,所以我被困在如何解决这个问题上。现在处理这个问题的正确方法是什么?

【问题讨论】:

  • 在弹出 VC_B 时将数组重新传递给 VC_A
  • 我认为这篇博文解释了 Swift 专注于将基本数据结构表示为值,而不是为方便起见的引用 - medium.com/swift-programming/… 我怀疑你可以使用 NSArray 来获得类似于 Objective-c 的东西风格,但 Swift 有不同的做事方式,你可能想重新评估你的方法,使其更加 Swift 风格。
  • 我认为即使在 Objective-C 中,这也是问题的错误解决方案。为了依赖这种东西而给类提供可变的公共属性是一个非常危险的提议……尤其是当您完全进入应用程序的多线程领域时。

标签: ios swift pass-by-reference


【解决方案1】:

您仍然可以在 Swift 中通过将属性设为 NSMutableArray 来执行此操作,就像以前一样。如果您要求,基础类型仍然存在。但这在 ObjC 和 Swift 中都是糟糕的设计。它会在远处创建令人毛骨悚然的动作(当事情神奇地改变不属于调用的值时)并且可能会破坏 MVC(如果数据是持久的,它应该存在于模型中,而不是视图控制器中)。

Cocoa 中有两种常见的模式:将数据存储在模型中,或者通过委托传递。

如果这个数组表示某种持久状态(例如系统中的项目列表),那么它属于模型层,两个视图控制器都应该在那里读取和操作它,而不是通过相互通信。 (见Model-View-Controller。)

如果这个数组是一个临时的数据片段(例如从一个列表中选择),那么调用的 VC 应该将自己设置为接收 VC 的委托,并且当接收 VC 完成时,它应该将数据传回给它的代表。 (见Delegates and Data Sources。)

【讨论】:

  • 使用 NSMutableArray 让我暂时放弃了解决方案
【解决方案2】:

如果您使用标准的 Swift Array,这是一个值类型,您必须使用包装器或无类型的 NSArray

// a generic wrapper class
class Reference<T> {
    var value: T
    init(_ val: T) { value = val }
}

// Usage
class ViewController1 {
    static var list = Reference<[Int]>([])
}

class ViewController2 {
    static var list = Reference([3, 5, 7, 9, 11])

    func passToOtherVC() {
        ViewController1.list = self.list
    }
}

如果您想改变数组,您应该始终更改 Reference 对象的 value 属性。

【讨论】:

    【解决方案3】:

    在 Swift 中,对象是通过引用自动传递的。 NSArray 是一个 Objective C 类(通过引用传递),而 Array 是一个结构体(通过值传递)。

    因此,如果您正在使用 NSMutableArray,则该数组已经通过引用传递。

    【讨论】:

      【解决方案4】:

      就像一个潜在的概念证明来补充我对这个问题的评论 - 可以使用 Objective-C NSMutableArray 来完成这项任务:

      class A {
          var x: NSMutableArray = NSMutableArray(capacity: 12)
      }
      
      class B {
          var y: NSMutableArray!
      }
      
      let a = A()
      let b = B()
      
      b.y = a.x
      
      b.y[0] = 123
      
      assert(a.x[0] === b.y[0])
      

      不过,这种方法并不遵循 IMO 处理数据结构的 Swift 风格。

      【讨论】:

        猜你喜欢
        • 2019-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-16
        • 2014-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多