Weakify Strongify today.
Let’s look at the implementation first:
Method 1: Traditional writing:
#ifndef weakify #if __has_feature(objc_arc) #define weakify( x ) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wshadow\"") \ autoreleasepool{} __weak __typeof__(x) __weak_##x##__ = x; \ _Pragma("clang diagnostic pop") #else #define weakify( x ) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wshadow\"") \ autoreleasepool{} __block __typeof__(x) __block_##x##__ = x; \ _Pragma("clang diagnostic pop") #endif #endif #ifndef strongify #if __has_feature(objc_arc) #define strongify( x ) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wshadow\"") \ try{} @finally{} __typeof__(x) x = __weak_##x##__; \ _Pragma("clang diagnostic pop") #else #define strongify( x ) \ _Pragma("clang diagnostic push") \ _Pragma("clang diagnostic ignored \"-Wshadow\"") \ try{} @finally{} __typeof__(x) x = __block_##x##__; \ _Pragma("clang diagnostic pop") #endif #endifCopy the code
For example, RAC
#define weakify(...) \
autoreleasepool {} \
metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
#define strongify(...) \
try {} @finally {} \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
metamacro_foreach(rac_strongify_,, __VA_ARGS__) \
_Pragma("clang diagnostic pop")Copy the code
Today, we’ll explain how RAC implements this method.
Their main role is to manage references to self within the block:
@weakify(self); // define a __weak self_weak_ variable [RACObserve(self, name) subscribeNext:^(NSString *name) {@strongify(self); Self_weak self.outputLabel.text = name;}];Copy the code
Autoreleasepool {} is a macro that doesn’t do anything. And metamacro_foreach_CXt, let’s go in layer by layer
For the first time:
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)Copy the code
Keep clicking
#define metamacro_concat(A, B) \
metamacro_concat_(A, B)Copy the code
Then point
#define metamacro_concat_(A, B) A ## BCopy the code
In the end, it was discovered that C is a combination of two operators into one operator. #define rac_weakIfy_ (INDEX, CONTEXT, VAR) \ CONTEXT typeof__(VAR) metamacro_concat(VAR, weak) = (VAR); ‘typedef splicing into –, damn this have to install force…
The two macros must come in pairs, weak then strong. This is a good way to manage references to self within a Block. Of course, if you are a loser who doesn’t like to use yellow macros, you can write it in native code
__weak typeof(self) weakSelf = self;
self.Button.rac_command = [[RACCommand alloc] initWithEnabled:textSig signalBlock:^RACSignal *(NSString * input) {
__strong typeof(weakSelf) strongSelf = weakSelf;
return nil;
}];Copy the code
The more details, the more doomed to success or failure. @Dylan.