没有函数如何通过引用传递数组?迅速

dav*_*vid 3 pass-by-reference ios swift ios8 ios9

我有这门课:

class MainView:UIView{

    var categories:[Category]!

}
Run Code Online (Sandbox Code Playgroud)

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

所以,如果我这样做:

let mainView  = MainView()
mainView.categories = categoriesData.
Run Code Online (Sandbox Code Playgroud)

然后它按值传递它.

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

class MainView:UIView{

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

    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

vac*_*ama 6

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)
Run Code Online (Sandbox Code Playgroud)

在上述步骤1中,存在的只有一个副本[1, 2, 3, 4, 5]在存储器中,并且a,bc对它的引用.

a在步骤2中修改时,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]
Run Code Online (Sandbox Code Playgroud)
  • 在步骤1,创建朋友阵列.它由局部变量引用friends.

  • createFredsFriends()返回时该引用消失,并且friends在步骤2中由局部变量保持对该数组的唯一引用.已经传递了该数组的所有权.

  • 在步骤3,对数组的第二个引用已分配给friends属性fred.

  • 在步骤4,createFred()已返回,因此局部变量friends消失,不再引用该数组.唯一的引用是在fred变量持有的对象的属性中fred.

因此,数组创建一次,创建了几个引用,最后只有一个对数组的引用,所有这些都是在没有单个复制操作的情况下完成的.


由于Swift数组是值类型并在更改时复制,因此您无法传递数组,而是希望在复制时更新原始数据.如果您需要该级别的功能,则可以为该数组创建一个类包装器,然后始终通过该类的实例访问该数组.

在这里,我修改了前面的示例,以显示它将如何工作:

// 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()
Run Code Online (Sandbox Code Playgroud)