@strongify(self) 和 @weakify(self) 宏

宏展开

首先看一下宏展开的样子

strongify(self) = autoreleasepool {} Pragma(“clang diagnostic push”) _Pragma(“clang diagnostic ignored "-Wshadow"”) attribute((objc_ownership(strong))) typeof(self) self = self_weak; _Pragma(“clang diagnostic pop”)

weakify(self) = autoreleasepool {} attribute((objc_ownership(weak))) typeof(self) self_weak_ = (self);

如何打印宏展开内容

宏定义中包含两个运算符: # 和 ##

  • # 运算符将一个宏的参数转换为字符串字面量, 即在对它所引用的宏变量通过替换后在其左右各加上一个双引号;
  • ## 被称为 连接符, 它是一种预处理运算符, 用来把两个语言符号组合成单个语言符号.

打印宏展开内容时, 使用到了#运算符

定义展开宏内容的宏

#define CONNECT(x)         @#x
#define INPUT(x)           CONNECT(x)

INPUT(x) 通过传入一个宏, 即可返回该宏展开后的内容字符串.

问题: 为何不能直接使用#define INPUT(x) @#x, 必须要使用宏嵌套;

首先,C语言的宏是允许嵌套的,其嵌套后,一般的展开规律像函数的参数一样:先展开参数,再分析函数,即由内向外展开。但是,注意: (1) 当宏中有#运算符时,参数不再被展开; (2) 当宏中有##运算符时,则先展开函数,再展开里面的参数; 关于嵌套宏的使用

打印宏展开后的内容

    NSString *strongify = INPUT(strongify(self));
    NSLog(@"strongify(self) = %@", strongify);
    
    NSString *weakify = INPUT(weakify(self));
    NSLog(@"weakify(self) = %@", weakify);
strongify(self) = autoreleasepool {} _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") __attribute__((objc_ownership(strong))) __typeof__(self) self = self_weak_; _Pragma("clang diagnostic pop")

weakify(self) = autoreleasepool {} __attribute__((objc_ownership(weak))) __typeof__(self) self_weak_ = (self);

浅析strongify(self) 和 weakify(self)

浅析:

weakify(self) = autoreleasepool {} attribute((objc_ownership(weak))) typeof(self) self_weak_ = (self);

@autoreleasepool {} __weak __typeof__(self) self_weak = self; 转换后的弱引用self前增加一个自动释放池.

打印#define YQWeakSelf autoreleasepool {} __weak __typeof__(self) self_weak = self;

结果为:yqWeakSelf(self) = autoreleasepool {} attribute((objc_ownership(weak))) typeof(self) self_weak = self;

是不是已经很接近weakify(self)了😄

同理可以打印#define YQWeakSelf autoreleasepool {} __weak __typeof__(self) self_weak = self; 只不过缺少一个自动释放池和强制忽略警告代码

Loading Disqus comments...
Table of Contents