An experiment on Swift references
In Swift, we have 4 different kinds of references, so I did a little experiment to help me to have a better understanding of them. There are many articles already explained the difference between these different kinds and their use case respectively, in a detailed and understandable manner, therefore in this post I'll focused on what will actually happened if you deallocate them.
Setting up
First we have this piece of code
class MagicBox {
var strongObj: AnyObject?
weak var weakObj: AnyObject?
/// this is equivalent to unowned(safe)
/// don't make this optional in real project
unowned var unownedObject: AnyObject?
unowned(unsafe) var unownedUnsafeObject: AnyObject?
init(strongObj: AnyObject, weakObj: AnyObject, unownedObj: AnyObject, unownedUnsafeObj: AnyObject) {
self.strongObj = strongObj
self.weakObj = weakObj
self.unownedObject = unownedObj
self.unownedUnsafeObject = unownedUnsafeObj
}
func all() -> String {
// workaround so to access these variables first
if (self.unownedUnsafeObject == nil) {}
if (self.unownedObject == nil) {}
return "strongObj: \(strongObj)\nweakObj: \(weakObj)\nunownedObject: \(unownedObject)\nunownedUnsafeObject: \(unownedUnsafeObject)"
}
}
Then we create some objects and referenced them in our MagicBox
var strongObj: AnyObject? = NSObject()
var weakObj: AnyObject? = NSObject()
var unownedObj: AnyObject? = NSObject()
var unownedUnsafeObj: AnyObject? = NSObject()
var magicBox = MagicBox(strongObj: strongObj!, weakObj: weakObj!, unownedObj: unownedObj!, unownedUnsafeObj: unownedUnsafeObj!)
magicBox.all()
Here is the output:
strongObj: Optional(<NSObject: 0x600002cfcb80>)
weakObj: Optional(<NSObject: 0x600002cfcba0>)
unownedObject: Optional(<NSObject: 0x600002cfcc10>)
unownedUnsafeObject: Optional(<NSObject: 0x600002cfcc20>)
Now we try to set the value of strongObj
and weakObj
to nil, and here is what happened, the weakObj
is vanished but the strongObj
is still there.
strongObj: Optional(<NSObject: 0x600002c08cd0>)
weakObj: nil
unownedObject: Optional(<NSObject: 0x600002c08d60>)
unownedUnsafeObject: Optional(<NSObject: 0x600002c08d70>)
Next we are going to set unownedUnsafeObject
to nil, and we got an error
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x614744894bc0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
Finally is the unownedObject
, and we got a different error
error: Execution was interrupted, reason: signal SIGABRT.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.