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?
+3


source to share


3 answers


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

.

+1


source


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.

+2


source


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

0


source







All Articles