2017-05-28 1 views
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 
  • Quelqu'un peut-il expliquer s'il vous plaît, pourquoi userDataStore ne pointe pas profileInteractor.userDataStore!
  • Que dois-je faire, que userDataStore pointe vers lui?
+0

Cela pourrait aider: https://stackoverflow.com/questions/27364117/is-swift-pass-by-value-or-pass-by-reference – Alladinian

Répondre

1

pourquoi userDataStore ne pointe pas profileInteractor.userDataStore!

Dans cette ligne:

var profileInteractor = ProfileInteractor(userDataStore: UserDataStore()) 

Vous avez créé un nouvel objet ProfileInteractor et un nouvel objet UserDataStore. Ensuite, vous avez fait profileInteractor se référer à l'objet ProfileInteractor.

Dans la ligne suivante:

var userDataStore = profileInteractor.userDataStore 

Vous faites userDataStore se réfèrent au même objet que profileInteractor.userDataStore. Maintenant tout ce que vous faites à l'objet UserDataStore en utilisant userDataStore sera reflété sur profileInteractor.userDataStore car ils sont essentiellement la même chose.

Cependant, cette ligne change tout:

profileInteractor.userDataStore = nil 

Vous avez fait profileInteractor.userDataStore référence à rien. Ce NE DOIT PAS signifie que l'objet UserDataStore est détruit. Cela signifie simplement que vous ne pouvez plus utiliser profileInteractor.userDataStore pour accéder à l'objet UserDataStore. Mais devinez ce qui fait toujours référence à l'objet UserDataStore? userDataStore!

Donc, la réponse à votre question est que userDataStore pointait vers le même objet que profileInteractor.userDataStore, jusqu'à ce que vous définissiez profileInteractor.userDataStore à zéro.

Que dois-je faire, que userDataStore pointe vers lui?

Eh bien, vous l'avez déjà fait. Vous venez de faire profileInteractor.userDataStore point à quelque chose d'autre dans la ligne de code suivante.Si vous voulez qu'une variable locale pointe toujours vers la même chose qu'une autre variable locale, votre code peut être assez compliqué, comme dans la réponse d'Ankit Thakur, avec des pointeurs et autres choses peu sûrs. Si vous transmettez la variable à une méthode, vous pouvez utiliser le mot-clé inout.

+0

Merci beaucoup. Maintenant, que j'ai vu ça, je pensais, c'est exactement comme ARC fonctionne ^^ – twofish

0

La copie d'une référence crée implicitement une instance partagée. Après une copie, deux variables, alors se référer à une seule instance des données, afin de modifier des données dans la seconde variable affecte également la

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 

sortie d'origine:

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 

Voici la belle référence de passe en valeur et passer par référence: https://developer.apple.com/swift/blog/?id=10

2

Je pense que vous êtes malentendu dans le but d'attribuer nil-userDataStore.

Affecter userDataStore à nil signifie qu'il ne pointera à rien, c'est-à-dire qu'il sera détruit; Cela devrait pas conduit à laisser profileInteractor.userDataStore être également nil. nil dans Swift signifie qu'il n'y a rien du tout, cela signifie not qu'il s'agit d'un pointeur vers un espace vide dans la mémoire.

Pour le rendre plus clair, vérifiez l'extrait de code suivant:

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 this aidé.