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];
}];
Cœur
  • 37,241
  • 25
  • 195
  • 267
sarunw
  • 8,036
  • 11
  • 48
  • 84
  • 2
    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_. – holex Mar 02 '15 at 12:02

2 Answers2

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.

rounak
  • 9,217
  • 3
  • 42
  • 59
  • 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? – sarunw Mar 02 '15 at 12:09
  • 2
    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. – rounak Mar 02 '15 at 12:15
  • So this strong is to prevent `EXC_BAD_ACCESS ` causing from using deallocated self in block right? – sarunw Mar 03 '15 at 04:07
  • 1
    @sarunw 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. – rounak Mar 03 '15 at 07:54
-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".

Míng
  • 2,500
  • 6
  • 32
  • 48