在Swift中将类成员的引用分配给变量

3
class UserDataStore {
}

class ProfileInteractor {

    var userDataStore: UserDataStore?

    init(userDataStore: UserDataStore?) {
        self.userDataStore = userDataStore
    }
}

var profileInteractor = ProfileInteractor(userDataStore: UserDataStore())
var userDataStore = profileInteractor.userDataStore
profileInteractor.userDataStore = nil

print(profileInteractor.userDataStore == nil) // prints: true
print(userDataStore == nil) // prints: false
print(userDataStore === profileInteractor.userDataStore) // prints: false
  • 请问,为什么userDataStore没有指向profileInteractor.userDataStore呢?
  • 我该怎么做才能使userDataStore指向它?

这可能会有所帮助:https://dev59.com/7l4c5IYBdhLWcg3w7-B4 - Alladinian
3个回答

2
我认为你对于给userDataStore赋值nil的目的存在误解。
userDataStore赋值为nil意味着它不会指向任何东西,即它将被销毁;这应该不会导致profileInteractor.userDataStore也成为nil。在Swift中,nil表示根本没有任何东西,而不是指向内存中空位置的指针。
为了更清楚地说明问题,请查看以下代码片段:
class UserDataStore: CustomStringConvertible {
    var title: String?

    var description: String {
        return "\(title)"
    }

    init(_ title: String) {
        self.title = title
    }
}

class ProfileInteractor {

    var userDataStore: UserDataStore?

    init(userDataStore: UserDataStore?) {
        self.userDataStore = userDataStore
    }
}

var profileInteractor = ProfileInteractor(userDataStore: UserDataStore("Hello"))
var userDataStore = profileInteractor.userDataStore

print(userDataStore === profileInteractor.userDataStore) // prints: true
print(profileInteractor.userDataStore) // prints: Optional(Optional("Hello"))

userDataStore?.title = "Bye"

print(profileInteractor.userDataStore) // prints: Optional(Optional("Bye"))

userDataStore = nil

print(profileInteractor.userDataStore) // prints: Optional(Optional("Bye"))

希望这有所帮助。

1
在这行代码中,为什么userDataStore没有指向profileInteractor.userDataStore呢?
var profileInteractor = ProfileInteractor(userDataStore: UserDataStore())

您创建了一个新的ProfileInteractor对象和一个新的UserDataStore对象。然后,您让profileInteractor引用ProfileInteractor对象。
在接下来的一行中:
var userDataStore = profileInteractor.userDataStore

你正在使userDataStore引用与profileInteractor.userDataStore相同的对象。现在,通过使用userDataStoreUserDataStore对象所做的任何更改都将反映在profileInteractor.userDataStore上,因为它们本质上是相同的东西。
然而,这一行改变了一切:
profileInteractor.userDataStore = nil

您使profileInteractor.userDataStore指向了空值。这并不意味着UserDataStore对象被销毁。这只是意味着您不能再使用profileInteractor.userDataStore来访问UserDataStore对象。但是,猜猜仍然在引用UserDataStore对象?是userDataStore!因此,您问题的答案是,userDataStore曾经指向与profileInteractor.userDataStore相同的对象,直到您将profileInteractor.userDataStore设置为nil。

我该怎么做,才能让userDataStore指向它?

嗯,您已经做到了。您只是在下一行代码中使profileInteractor.userDataStore指向了其他东西

如果您想让一个本地变量始终指向另一个本地变量指向的内容,您的代码可能会变得非常混乱,就像Ankit Thakur的答案一样,需要使用不安全指针等。如果您要将变量传递给方法,则可以使用inout关键字。


非常感谢。现在我看到了这个,我想,这就像 ARC 的工作方式一样 ^^ - twofish

0
复制引用会隐式地创建一个共享实例。在复制后,两个变量都指向相同的数据实例,所以修改第二个变量中的数据也会影响到原始数据。
class UserDataStore {
    var inst:String?


    init(obj: String?) {
        self.inst = obj
    }

}

class ProfileInteractor {

    var userDataStore: UserDataStore?

    init(userDataStore: UserDataStore?) {
        self.userDataStore = userDataStore
    }
}

var profileInteractor = ProfileInteractor(userDataStore: UserDataStore(obj: "10"))
var userDataStore = profileInteractor.userDataStore

withUnsafePointer(to: &(profileInteractor.userDataStore)) {
    print(" profileInteractor.userDataStore has address: \($0)")
}
withUnsafePointer(to: &userDataStore) {
    print("userDataStore has address: \($0)")
}

withUnsafePointer(to: &(((profileInteractor.userDataStore) as! UserDataStore).inst)) {
    print(" profileInteractor.userDataStore value inst has address: \($0)")
}
withUnsafePointer(to: &(((userDataStore) as! UserDataStore).inst)) {
    print("userDataStore value inst has address: \($0)")
}

print(userDataStore)
print(profileInteractor.userDataStore)

profileInteractor.userDataStore = nil

print(profileInteractor.userDataStore == nil) // prints: true
print(userDataStore == nil) // prints: false

print(userDataStore === profileInteractor.userDataStore) // prints: false

输出:

 profileInteractor.userDataStore has address: 0x0000610000031230
userDataStore has address: 0x000000010e8103e0
 profileInteractor.userDataStore value inst has address: 0x000061000004f5b0
userDataStore value inst has address: 0x000061000004f5b0
Optional(__lldb_expr_35.UserDataStore)
Optional(__lldb_expr_35.UserDataStore)
true
false
false

这里是有关按值传递和按引用传递的良好参考: https://developer.apple.com/swift/blog/?id=10


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接