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.