Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Referencing [weak self] as self? inside animateWithDuration causes crash

If I declare [weak self] on a closure and reference self as self? inside UIView.animateWithDuration the app will crash:

someFunc() { [weak self] (success) -> Void in
    UIView.animateWithDuration(0.25) {
        self?.someView.alpha = 1;
    }
}

with a message sent to deallocated instance

but if I optionally unwrap self ahead of time it doesn't

someFunc() { [weak self] (success) -> Void in
    if let weakself = self {
        UIView.animateWithDuration(0.25) {
            weakself.someView.alpha = 1;
        }
    }
}

Why is that, I would think that it doesn't matter which way I reference the weak self since it should "just" optionally unwrap self? correctly. For context this is done in a UICellView which is deallocated when I leave the UICollectionViewController

EDIT: Filed a bug with apple: #23492648

like image 472
Shizam Avatar asked Nov 11 '15 01:11

Shizam


1 Answers

I think the problem here is that self is special. You've passed the reference to self weakly into the anonymous function to prevent a retain cycle, but there isn't really an Optional wrapping self in this story. Thus, the syntactic sugar self?.someView.alpha = 1 — and remember, it is merely syntactic sugar — doesn't work.

It may be that Apple will regard this as a bug; or maybe not. But either way, the solution is to do formulaically exactly what you are doing in the second example: do the weak-strong dance explicitly.

like image 179
matt Avatar answered Sep 22 '22 18:09

matt