如何在没有函数的情况下通过引用传递数组? swift

How to pass array by reference without function ? swift

我有这个class:

class MainView:UIView{

    var categories:[Category]!

}

我想设置类别 arg,但我需要通过引用而不是值来传递它。因为它更高效更好。

所以如果我这样做:

let mainView  = MainView()
mainView.categories = categoriesData.

然后按值传递。

如果我需要通过引用传递它,我可以通过使用 MainView() 中的函数来做到这一点

class MainView:UIView{

    var categories:[Category]!
    fun setCategories(inout categories: Int){
            self.categories = categories;

    }

}

但如果我不想使用 set 函数,我怎么能通过引用传递它。 例如

mainView.categories = &categoriesData. 但这不起作用?谢谢

Swift 在处理数组时使用 ARC(自动引用计数),它会延迟复制数组,直到其中一个副本被修改:

例如:

var a = [1, 2, 3, 4, 5]
let b = a
let c = a   // 1

a.append(6) // 2

print(a.count)
print(b.count)
print(c.count)

在上面的第1步中,内存中只有一份[1, 2, 3, 4, 5]abc都是对它的引用

当在第2步修改a时,Swift给出a和数组的新副本,bc继续引用原始数组。所以现在内存中有 2 个数组副本。


让我们看一个更复杂的例子:

class Person: CustomStringConvertible {
    let name: String
    var friends: [Person] = []

    init(name: String) {
        self.name = name
    }

    var description: String { return name }
}

func createFredsFriends() -> [Person] {
    let barney = Person(name: "Barney")
    let wilma = Person(name: "Wilma")
    let betty = Person(name: "Betty")
    let friends = [barney, wilma, betty]  // 1

    return friends
}

func createFred() -> Person {
    let fred = Person(name: "Fred")

    let friends = createFredsFriends() // 2
    fred.friends = friends             // 3

    return fred
}

let fred = createFred()  // 4

print(fred.friends)  // [Barney, Wilma, Betty]
  • 在第 1 步中,创建了朋友数组。它被局部变量friends.

  • 引用
  • 此引用在 createFredsFriends() returns 时消失,并且对数组的唯一引用由第 2 步的局部变量 friends 持有。所有权已通过数组。

  • 在第 3 步,数组的第二个引用已分配给 fredfriends 属性。

  • 在第4步,createFred()已经返回,所以局部变量friends没有了,不再引用数组。唯一的引用是在 fred 对象的 属性 中,它由变量 fred.

  • 保存

所以这个数组被创建了一次,创建了多个对它的引用,最后只有一个对数组的引用,所有这些都是在没有一个复制操作的情况下完成的。


由于 Swift 数组是值类型并且在更改时被复制,您不能传递一个数组然后期望在复制时更新原始数组。如果您需要该级别的功能,您可以为数组创建一个 class 包装器,然后始终通过该 class.

的实例访问该数组

这里我修改了前面的例子来展示它是如何工作的:

// Class to wrap array so that everyone references the same copy
class FriendsWrapper {
    var friends: [Person]

    init(friends: [Person]) {
        self.friends = friends
    }
}

class Person: CustomStringConvertible {
    let name: String
    var friendsWrapper: FriendsWrapper?

    init(name: String) {
        self.name = name
    }

    func addFriend(friend: Person) {
        if let wrapper = friendsWrapper {
            wrapper.friends.append(friend)
        } else {
            friendsWrapper = FriendsWrapper(friends: [friend])
        }
    }

    var description: String { return name }
}

func createFredsFriends() -> [Person] {
    let barney = Person(name: "Barney")
    let wilma = Person(name: "Wilma")
    let betty = Person(name: "Betty")
    let friends = [barney, wilma, betty]

    return friends
}

func createFred() -> Person {
    let fred = Person(name: "Fred")

    let friendsWrapper = FriendsWrapper(friends: createFredsFriends())
    fred.friendsWrapper = friendsWrapper

    // Add friend to Fred object
    fred.addFriend(Person(name: "Bam Bam"))

    // Copy of array in local friendsWrapper is updated
    print(friendsWrapper.friends)  // [Barney, Wilma, Betty, Bam Bam]

    return fred
}

let fred = createFred()