Если вам нужно передать массив (или любой другой тип значения) по ссылке, вы могли бы пройти через промежуточную структуру, которая управляет перенаправлением для вас.
[ПРАВКА] изменено для использования KeyPaths, доступных в Swift 4.
// Generic class to hold a "weak" reference to a property from an object
// including properties that are valued types such as arrays, structs, etc.
// This is merely an encapsulation of Swift's native KeyPath feature
// to make the code a bit more readable and simpler to use
//
class ReferenceTo<ValueType> { var value:ValueType! { get { return nil} set {} } }
class Reference<OwnerType:AnyObject,ValueType>:ReferenceTo<ValueType>
{
internal weak var owner:OwnerType!
internal var property:ReferenceWritableKeyPath<OwnerType,ValueType>! = nil
internal var valueRef:KeyPath<OwnerType,ValueType>! = nil
init(_ owner:OwnerType, _ property:ReferenceWritableKeyPath<OwnerType,ValueType>)
{ (self.owner,self.property) = (owner,property) }
init(_ owner:OwnerType, get valueRef:KeyPath<OwnerType,ValueType>)
{ (self.owner,self.valueRef) = (owner,valueRef) }
override var value:ValueType!
{
get { return valueRef != nil ? owner?[keyPath:valueRef] : owner?[keyPath:property] }
set { owner?[keyPath:property] = newValue }
}
}
С помощью этого универсального класса вы можете создавать ссылки на свойства ценного типа экземпляров объекта и манипулировать ими в любом месте вашего кода, как если бы свойство ценного типа было ссылочным типом.
// Example class with a read/write and a read-only property:
class MyObject
{
var myArray = [1,2,3,4]
var total:Int { return myArray.reduce(0,+) }
}
var instance:MyObject! = MyObject()
// create a reference to the array (valued type)
// that can be used anywhere and passed around as a parameter
let arrayRef = Reference(instance, \.myArray)
// the value is accessed and manipulated using the
// "value" property of the reference
arrayRef.value.remove(at:2)
arrayRef.value.append(5)
print(instance.myArray) // [1,2,4,5]
// Read-only properties can also be manipulated as
// references
let valueRef = Reference(instance, get:\.total)
print(valueRef.value) // 12
Класс Reference позволяет передавать значение в качестве ссылки на параметры функции
// a function that expects a reference to an array
// would be declared as follows
func changeArray(_ array:ReferenceTo<[Int]>)
{ array.value.insert(9, at: 1) }
// the reference can also be used as an inout parameter
func shift(_ array:inout [Int])
{ array = Array(array.dropFirst()) + Array(array.prefix(1)) }
changeArray(arrayRef)
shift(&arrayRef.value!)
print(instance.myArray) // [9,2,4,5,1]
...
// the reference uses a weak link to the owner
// of the referenced property or value
// so there will be no strong reference cycle issues even
// if the reference is used in an object held strongly
// by the owner itself
instance = nil
print(arrayRef.value) // none ... no more value after the owner is gone