swift 中的视图控制器之间通过引用传递数组
Pass array by reference between viewcontrollers in swift
当使用 Objective-C 时,我会将 NSMutableArray
从一个视图控制器 VC_A
传递到另一个 VC_B
,只需在 [=14] 中分配一个 属性 =]作为
VC_B.list = self.list
自己在哪里 VC_A
当视图控制器从导航堆栈弹出时,它允许在 VC_A
中的列表中看到列表中 VC_B
中所做的更改。
但是在 Swift 中,由于数组是按值传递的,因此如上所述分配不起作用,所以我不知道如何解决这个问题。现在处理这个问题的正确方法是什么?
在Swift中,对象自动通过引用传递。 NSArray 是一个 Objective C class(按引用传递),其中 Array 是一个结构(按值传递)。
因此,如果您正在使用 NSMutableArray,则数组已经通过引用传递。
作为补充我对问题的评论的潜在概念证明 - 可以使用 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 风格。
如果您使用标准 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
属性。
您仍然可以在 Swift 中通过将 属性 设为 NSMutableArray
来执行此操作,就像以前一样。如果您要求,基础类型仍然存在。但这在 ObjC 和 Swift 中都是糟糕的设计。它会在远处产生怪异的动作(当事物神奇地改变不属于调用的值时)并且可能会破坏 MVC (如果数据是持久的,它应该存在于模型中,而不是在视图控制器中) .
Cocoa中有两种常见模式:将数据存储在模型中,或通过委托传递。
如果这个数组表示某种持久状态(例如系统中的项目列表),那么它属于模型层,两个视图控制器都应该在那里读取和操作它,而不是通过与每个对象进行通信其他。 (参见 Model-View-Controller。)
如果这个数组是一个短暂的数据片段(例如列表中的选择),那么调用 VC 应该将自己设置为接收 VC 的委托,并且当接收VC 完成后,它应该将数据传回给它的委托。 (参见 Delegates and Data Sources。)
当使用 Objective-C 时,我会将 NSMutableArray
从一个视图控制器 VC_A
传递到另一个 VC_B
,只需在 [=14] 中分配一个 属性 =]作为
VC_B.list = self.list
自己在哪里 VC_A
当视图控制器从导航堆栈弹出时,它允许在 VC_A
中的列表中看到列表中 VC_B
中所做的更改。
但是在 Swift 中,由于数组是按值传递的,因此如上所述分配不起作用,所以我不知道如何解决这个问题。现在处理这个问题的正确方法是什么?
在Swift中,对象自动通过引用传递。 NSArray 是一个 Objective C class(按引用传递),其中 Array 是一个结构(按值传递)。
因此,如果您正在使用 NSMutableArray,则数组已经通过引用传递。
作为补充我对问题的评论的潜在概念证明 - 可以使用 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 风格。
如果您使用标准 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
属性。
您仍然可以在 Swift 中通过将 属性 设为 NSMutableArray
来执行此操作,就像以前一样。如果您要求,基础类型仍然存在。但这在 ObjC 和 Swift 中都是糟糕的设计。它会在远处产生怪异的动作(当事物神奇地改变不属于调用的值时)并且可能会破坏 MVC (如果数据是持久的,它应该存在于模型中,而不是在视图控制器中) .
Cocoa中有两种常见模式:将数据存储在模型中,或通过委托传递。
如果这个数组表示某种持久状态(例如系统中的项目列表),那么它属于模型层,两个视图控制器都应该在那里读取和操作它,而不是通过与每个对象进行通信其他。 (参见 Model-View-Controller。)
如果这个数组是一个短暂的数据片段(例如列表中的选择),那么调用 VC 应该将自己设置为接收 VC 的委托,并且当接收VC 完成后,它应该将数据传回给它的委托。 (参见 Delegates and Data Sources。)