Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Memory Leaks in iOS

Blocks that are added to a notification center

typeof(self) __weak weakSelf = self;
[[[EDFlux sharedInstance] budgetStore] addChangeObserverWithBlock:^(NSNotification* note) {
    [weakSelf doSomething];
}];
EDFlux.sharedInstance().budgetStore.addChangeObserverWithBlock({ [weak self] (notification) -> Void in
    self?.doSomething()
})

which simply forwards to

- (id<NSObject>)addChangeObserverWithBlock:(void (^)(NSNotification* note))block
{
    return [self.notificationCenter addObserverForName:kFluxStoreChangedEventName object:nil queue:nil usingBlock:block];
}

Block as DI property

Say we have a definition like this:

class MyClass {

    var callback:(() -> ())?
    
    ...
}

Defining a callback that captures self strongly will create a memory leak. There are two options:

weak

If the block might persist beyond the life of self then you can use [weak self] and treat self as an optional.

myInstance.callback = { [weak self] in
    self?.doSomething()
}

And of course you can use an if let or guard here

myInstance.callback = { [weak self] in
    guard let strongSelf = self else { return }
    strongSelf.doSomething()
}

unowned

If you know that self will always be around during the life of the block then you can use [unowned self] so it is not captured strongly, but it also is not optional. Accessing self like this if self has been deallocated will crash the app.

myInstance.callback = { [unowned self] in
    self.doSomething()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment