RAC中的@weakify和@strongify浅析

其实如果我们打开Xcode中查看预编译之后宏被替换的结果我们就会发现@weakify(self)被替换成了下面这个

@autoreleasepool {} __attribute__((objc_ownership(weak))) __typeof__(self) self_weak_ = (self);
其实如果我们去查看下自己写的解决循环引用的代码,会然后查看下预编译之后的结果其实和上面的是一模一样的,除了你命名的名字不一样

__weak __typeof__(self) weakSelf = self;
其中__weak被替换成了__attribute__((objc_ownership(weak)))


然后我们其实再去看下面的这个@strongify(self)其实也是一样的道理,被替换成了,这里就是self_weak_赋值给新声明的局部变量self

@autoreleasepool {} __attribute__((objc_ownership(strong))) __typeof__(self) self = self_weak_;

然后我们点击进入@weakify中进去看会发现这样的内容

#define weakify(...) \
    rac_keywordify \
    metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)
首先补充一下_Pragma这个操作符具有与 #pragma 指令相同的功能,在C/C++标准中,#pragma是一条预处理的指令(preprocessor directive)。其实就是#pragma是用来向编译器传达语言标准以外的一些信息,在ios中其实我们会发现如果我们定义了这段代码, #pragma mark - UITableViewDelegate ,我们会看到其实编译器帮我们把代码进行了分块。然后由于#pragma 指令不能被用于宏定义中,因为编译器会将指令中的数字符号(“#”)认为为字符串化运算符 (#)。,由于_Pragma是一个操作符,因此可以被用在宏当中

就好比我们这么使用来消除某些API被废弃的警告

    #pragma clang diagnostic push  
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"  
    //code  
    #pragma clang diagnostic pop  
我们再去点击@strongify我们会发现下面的这些宏定义,下面其实也做了消息什么类型的警告,关于这个我们可以在后面这个链接去看报的Clang警告语义 http://fuckingclangwarnings.com/

#define strongify(...) \
    rac_keywordify \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic ignored \"-Wshadow\"") \
    metamacro_foreach(rac_strongify_,, __VA_ARGS__) \
    _Pragma("clang diagnostic pop")
其中的rac_keywordify其实就是下面的内容也就是说DEBUG模式下是autoreleasepool而release模式下就是try catch,所以其实我们在使用@weakify和@strongify的@其实代表的就是自动释放池前面的@和@try {} @catch (...) {}前面的@

#if DEBUG
#define rac_keywordify autoreleasepool {}
#else
#define rac_keywordify try {} @catch (...) {}
#endif
为什么要这么设计?分不同的模式下来判断。首先我们看下它官方的解释,其实可以这么理解就是当@try { } @catch(...) {}被添加到了前面。在这种情况下,Xcode 本身的错误提示能力能被抑制了,也就是说其实抑制了编译器对返回类型的警告,作用其实就是 不让编译器产生warnings。下面也有说使用@try/@catch来避免产生不必要的释放池

// Details about the choice of backing keyword:
//
// The use of @try/@catch/@finally can cause the compiler to suppress
// return-type warnings.
// The use of @autoreleasepool {} is not optimized away by the compiler,
// resulting in superfluous creation of autorelease pools.
//
// Since neither option is perfect, and with no other alternatives, the
// compromise is to use @autorelease in DEBUG builds to maintain compiler
// analysis, and to use @try/@catch otherwise to avoid insertion of unnecessary
// autorelease pools.







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值