I understand that you should use @weakify @strongify to avoid retain cycles but I don't completely understand how they actually achieve this?
-
1@jamieforrest I noticed you have edited this question. When I originally asked this question I definitely was referring to ReactiveCocoa in spite of the fact that these macros might originate in libextobjc, in the version I was using they are defined in a header file called RACEXTScope.h this file exists in ReactiveCocoa and is not an external dependency. I think we should maintain ReactiveCocoa in the title with libextobjc appended rather than replacing it. – nacross Oct 27 '14 at 04:19
-
Makes sense. I added it back. – Jamie Forrest Oct 27 '14 at 14:11
3 Answers
code before preprocess:
@weakify(self)
[[self.searchText.rac_textSignal
map:^id(NSString *text) {
return [UIColor yellowColor];
}]
subscribeNext:^(UIColor *color) {
@strongify(self)
self.searchText.backgroundColor = color;
}];
code after preprocess:
@autoreleasepool {} __attribute__((objc_ownership(weak))) __typeof__(self) self_weak_ = (self);
[[self.searchText.rac_textSignal
map:^id(NSString *text) {
return [UIColor yellowColor];
}]
subscribeNext:^(UIColor *color) {
@try {} @finally {}
__attribute__((objc_ownership(strong))) __typeof__(self) self = self_weak_; // 1
self.searchText.backgroundColor = color; //2
}];
1: define a new local variable “self”. this will shadow the global one.
2: so here we used the local variable “self”--self_weak_.
tips:
1.if we used self.xxx in block, we should place @strongify(self) over it.
2.don't forget use @weakify(self) to define the variable self_weak_.
(PS: I'm trying to learn English. I hope that you can understand what I'm saying.)
-
Correct me if I'm wrong- so, if I forgot to put `@strongify(self)` in the block, then the `self` I use in the block is still the original (not shadowed) self, and will be strongly retained? Still quite error-prone :( – Joseph Lin Apr 30 '14 at 16:57
-
Yes, that sounds about right. We need a a new Obj-C syntax with strongify / weakify built in! – fatuhoku May 05 '14 at 11:28
When writing the question I stared harder at the macro definitions and I think it works as you might guess.
@weakify creates a new weakly referenced variable of the same type you pass in and assigns the original value to it
@strongify creates a variable that matches the original variable but it exists in the local scope and assigns to it the variable created by @weakify

- 2,013
- 2
- 25
- 37
First and foremost, it matters what implementation of @weakify
& @strongify
you're using as these aren't part of the standard language.
Assuming you're using the ReactiveCocoa version, here's a nice article about what they are and how they work.
Here are a few relevant quotes:
Even the code not written by us can use
self
safely, e.g.NSAssert
macro. It's still possible to reference the realself
, by using anivar
. It leads to a warning, though, so it's a mistake that's easy to spotNow, you may ask: what if I forget to use
strongify
? This is a cool part:weakify
creates a new local variable, so if it's not used at all we get a warning.As you can imagine, if you forget to use
weakify
, butstrongify
is in its place, the compiler shows an error

- 2,318
- 18
- 20
-
My original question was about reactive cocoa. The inclusion of libextobjc was as result of an edit by other users who felt this question applied to that case as well, I cannot say if it does or does not. – nacross Jan 02 '16 at 03:44