class Owner {
var name: String
var pet: Pet?
init(name: String) {
self.name = name
print("Owner \(name) created.")
}
deinit {
print("Owner \(name) deallocated.")
}
}
class Pet {
var name: String
// Using 'weak' to avoid strong reference cycle
weak var owner: Owner?
init(name: String) {
self.name = name
print("Pet \(name) created.")
}
deinit {
print("Pet \(name) deallocated.")
}
}
class UnownedPet {
var name: String
// Using 'unowned' assuming the pet always has an owner
unowned var owner: Owner
init(name: String, owner: Owner) {
self.name = name
self.owner = owner
print("UnownedPet \(name) created.")
}
deinit {
print("UnownedPet \(name) deallocated.")
}
}
// Example usage:
// Creating an owner and a pet with a 'weak' reference
var owner: Owner? = Owner(name: "John")
var pet: Pet? = Pet(name: "Fido")
owner?.pet = pet
pet?.owner = owner
owner = nil // Owner deallocated, pet's 'weak' reference becomes nil
pet = nil // Pet deallocated
// Creating an owner and an unowned pet
var unownedOwner: Owner? = Owner(name: "Jane")
var unownedPet: UnownedPet? = UnownedPet(name: "Whiskers", owner: unownedOwner!)
unownedOwner?.pet = unownedPet
// unownedPet?.owner = unownedOwner // Uncommenting this line would result in a runtime crash
unownedOwner = nil // Owner deallocated, unownedPet's 'unowned' reference is now unsafe
// unownedPet = nil // Uncommenting this line would result in a runtime crash
// Output:
// Owner John created.
// Pet Fido created.
// Owner John deallocated.
// Pet Fido deallocated.
// Owner Jane created.
// UnownedPet Whiskers created.
// Owner Jane deallocated.