Should I use [weak me] in PromiseKit blocks?

PromiseKit states the following on their website :

Should I worry about saving loops?

tl; dr: its safe to use self in promise handlers.

It's safe:

somePromise.then { self.doSomething() } 

Provided that somePromise allows, the function passed to then will be released, so specifying [weak self] not required.

The indication [unoccupied self] is probably dangerous.

Are you telling me not to worry about keeping cycles ?!

No, it’s just that by default you won’t call save cycles when using PromiseKit. But it is still possible ...

Does this mean that I should never use [weak self] in PromiseKit blocks? Are there ever situations where I still need to use [weak self] ? How exactly does this prevent a retention cycle?

+6
source share
2 answers

This documentation simply says that you don’t have to worry about PromiseKit representing “strong reference loops” (previously called “save loops”) because when the promise is executed and the block ends, these strong links are automatically resolved for you. The choice of strong and weak links is up to you.

For example, there is no need to keep a strong link to the rejected view controller if you simply update the interface elements on the scene that no longer exist. You would use weak in this scenario. But sometimes you need a strong link (for example, you can update the base model to reflect the success or failure of a promise).

The bottom line, all they say is that you should not let PromiseKit dictate strong and weak links, but rather it should be due to the wider design requirements of your application. The only tough rule of re PromiseKit is that you should avoid unowned .

+5
source

TL DR: Continue to use [weak self] in PromiseKit blocks to prevent objects from living longer than necessary.


A few things can be noted. Firstly, there are two main reasons to use [weak self] in a block:

  • Save Cycle Prevention
  • Preventing objects from living longer than necessary

Secondly, PromiseKit creates a save loop when you call this block of code. self usually held on somePromise , and somePromise held on self . The reason they say you shouldn't worry about this hold cycle is because PromiseKit automatically breaks the save cycle. When then freed, somePromise will no longer be held on self , thereby breaking the save loop.

So, we know that we don’t need to worry about issue # 1 with PromiseKit blocks, but what about issue # 2?

Imagine that the view controller is disconnected from the promise of the network request and that it will take 30 seconds until this promise is resolved. Now, before it is allowed, the user clicks the back button. Usually UIKit is going to free up the view controller since it is no longer displayed on the screen, and the system can save resources. However, since you indicated self in the promise, it can no longer be released. This means that the view controller will live 30 seconds longer in memory than necessary.

The only way to solve problem # 2 is to use [weak self] inside the block.

Note. It can be argued that when your view controller returns, you must cancel the ongoing promise in any case so that it releases the self trick. However, figuring out when the view manager should be freed is not an easy task . It's much easier to let UIKit handle the logic for you, and if you really need to do something when the view manager is freed up by injecting it into the dealloc controller dealloc . This will not work if the block is held tightly on the view controller.


Update: it seems that one of the authors spoke about this and explained the reasons for making these recommendations:

In fact, preserving self is probably what you want to allow the promise to be resolved before self is released.

+4
source

All Articles