I'm trying a simple example as seen here:
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-XID_88
And this is my code. (Ignore other possible code, this is a empty project with this code written inside an empty UIViewcontroller viewDidLoad)
dispatch_async(dispatch_get_main_queue()) {
[unowned self] in
println(self)
}
I don't understand why it crashes when I run the pro
- thread #1: tid = 0x1a796, 0x00284d18 libswiftCore.dylib`_swift_release_slow + 8, queue =
'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1,
address=0x458bc681)
Did something changed on the latest beta(5) and this is not supported anymore?
Thanks
edit:
Interesting that this code works on Objc
__weak MyViewController *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@", weakSelf);
});
edit2:
The explanation on this link : Shall we always use [unowned self] inside closure in Swift on the difference of weak and unowned is wrong.
It's not just that weak nils and unowned doesn't. If that's the case, this should crash as well:
dispatch_async(dispatch_get_main_queue()) {
[weak self] in
println(self)
}
but it doesn't, and it prints the pointer, so, it's not nil.
[Unowned self]
makes it so the closure does not create a strong reference to self
and it does not automatically set it to nil
if it gets deallocated either. By the time the async method is executed, self has been deallocated. That is why you are getting the crash.
It certainly doesn't make sense to use unowned
in a one time asynchronous call. It would be better to capture a strong reference to it to be sure it sticks around. There still won't be a strong reference cycle because self
does not own the closure.
Side Note: This cannot be all of your code as self
isn't defined anywhere in your code.
unowned
and weak
are two different things. In Objective-C, unowned
is called unsafe unretained
. You can use weak
in both languages. weak
means that the runtime will automatically convert the reference to nil
if the object is deallocated. unowned
or unsafe unretained
means that it will not be set to nil
for you (which is why it is called "unsafe" in Objective-C.
Unowned
should only ever be used in circumstances where the object will never be deallocated. In those circumstances, use weak
.
Keep in mind, that if you capture a variable as weak
in Swift, the reference will be made an optional so to use it you will have to unwrap it:
dispatch_async(dispatch_get_main_queue()) {
[weak self] in
if let actualSelf == self {
// do something with actualSelf
}
// you can still print the "wrapped" self because it is fine to print optionals
// even if they are `nil`
println(self)
}
But to be clear, it would still be best to use a strong reference in this circumstance:
dispatch_async(dispatch_get_main_queue()) {
println(self)
}