What is the reason of @strongify
Asked Answered
S

2

7

In ReactiveCocoa there is macro to prevent retain cycle @weakify and @strongify. From my understanding @weakify do something like what I usually do that is create __weak reference for using in the block, but what about @strongify?

Why do I need to make it strong again in the block?

Here is some sample usage:

@weakify(self);
[RACObserve(self, username) subscribeNext:^(NSString *username) {
    @strongify(self);
    [self validateUsername];
}];
Semifluid answered 2/3, 2015 at 11:53 Comment(1)
you don't need to make a strong reference again inside the block in that situation what you have posted, it would not make any difference – but if you'd refer multiple times to the same self object and you want to be sure the self is valid until the block runs out of its scope (so your block won't make a half-done job on your self), you need to get it strong.Cronk
L
10

If you just use a weak reference within the block, self can get deallocated while the block is being executed. But if you want to ensure that self stays in memory until the block finishes execution, you have to convert the weak reference back to strong.

Lottie answered 2/3, 2015 at 12:1 Comment(4)
But if self is deallocated doesn't that mean I have no interest in this block anymore? It shouldn't even execute since it got deallocated along with self right?Semifluid
Well, that depends on your use case really. Besides if self gets deallocated before the block begins execution, strongSelf would still be nil. The main idea is the scenario when self could get deallocated in the middle of the execution of the block. To prevent deallocation in the middle of execution, you use strongify.Lottie
So this strong is to prevent EXC_BAD_ACCESS causing from using deallocated self in block right?Semifluid
@Semifluid No you get EXC_BAD_ACCESS when references are assign. Weak references are automatically converted to nil once the object is deallocated. strongify is basically when you want to ensure the object shouldn't get deallocated while the block is being executed.Lottie
V
-1

The @weakify(self) and @strongify(self) are equivalent to

__weak typeof(self) __weak_self__ = self; // weakify
[self setBlock:^{
    __strong typeof(__weak_self__) self = __weak_self__; // strongify
    [self doSomething];
}];

You must use __weak_self__ if there's no @strongify(self) in the block.

So, the most important reason is that you can still use self instead of __weak_self__ in the block. To avoid mistakes like this, copying [self doSomething]; into the block, but forget to change self to __weak_self__. It happens more than "self can get deallocated while the block is being executed".

Veroniqueverras answered 11/8, 2020 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.