Assigning a reference from a class member to a variable in Swift
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
- Can someone explain why userDataStore doesn't point to profileInteractor.userDataStore !?
- What should I do what the userDataStore points to?
source to share
why doesn't userDataStore point to profileInteractor.userDataStore !?
In this line:
var profileInteractor = ProfileInteractor(userDataStore: UserDataStore())
You have created a new object ProfileInteractor
and a new object UserDataStore
. Then you made ProfileInteractor
an object reference ProfileInteractor
.
On the next line:
var userDataStore = profileInteractor.userDataStore
You are making a UserDataStore
reference to the same object as profileInteractor.userDataStore
. Now, whatever you do to the object UserDataStore
with the help UserDataStore
will be reflected to profileInteractor.userDataStore
, because they are essentially the same thing.
However, this line changes everything:
profileInteractor.userDataStore = nil
You have made a profileInteractor.userDataStore
link to nothing. This does NOT mean that the object has been UserDataStore
destroyed. This means that you can no longer use profileInteractor.userDataStore
to access the object UserDataStore
. But guess what still applies to the object UserDataStore
? UserDataStore
!
So the answer to your question is what UserDataStore
points to the same object as profileInteractor.userDataStore
until you set profileInteractor.userDataStore
to nil.
What should I do what the userDataStore points to?
Well, you've already done that. You just pointed profileInteractor.userDataStore
to something else in the next line of code.
If you want a local variable to always point to the same thing that another local variable is pointing to, your code can get pretty messy, as in Ankit Thakur's answer, with unsafe pointers, etc. If you are passing a variable to a method, you can use the keyword inout
.
source to share
I think you are misunderstanding the purpose of the assignment nil
userDataStore
.
Purpose userDataStore
- nil
means that it will not point to anything, that is, it will be destroyed; This should not result in being profileInteractor.userDataStore
as well nil
. nil
in Swift means there is nothing, it does not
means it is a pointer to an empty space in memory.
To make it clearer, check the following code snippet:
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"))
Hope it helped.
source to share
Copying a link implicitly creates a shared instance. After copying, the two variables refer to one instance of the data, so changing the data in the second variable also affects the original
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
Output:
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
Here is a good link pass by value and pass by reference: https://developer.apple.com/swift/blog/?id=10
source to share