iOS 黑魔法 __attribute__(转摘)

原文地址http://blog.sunnyxx.com/2014/09/15/objc-attribute-cleanup/#rd
关于__attribute__的更详细的用法可以参考这一篇http://blog.csdn.net/ruixj/article/details/4274721

__attribute__是用于向编译器描述特殊的标识、检查或优化。下面通过介绍两个基本的用法:
1.__attribute__((cleanup(…))),用于修饰一个变量,在它的作用域结束之后可以自动执行一个指定的方法,如:

// 传入的参数是所修饰的变量的指针的地址
static void stringCleanUp(__strong NSString **string) {
    NSLog(@"%@",*string);
}
// 在某个方法中
{
   __strong NSString *string __attribute__((cleanup(stringCleanUp))) = @"Mr_C";    
}//当运行到这个作用域结束时,自动调用stringCleanUp

所谓的作用域结束包括大括号、return、goto、break、exception等各种情况。(当然可以修饰的不仅是string还有自定义的class和基本类型)。
需要注意的是当一个作用域内有多个cleanup变量,那么先修饰的要后执行,调用顺序是先入后出的栈式顺序。而且cleanup是先于这个对象的dealloc调用的。

进阶用法:
使用__attribute__((cleanup()))修饰block 可以实现通过宏定义让代码片段成对的出现,但是执行顺序缺可以是无序的状态。
//先简单定义一个block

static void blockCleanUp(__strong void(^*block)(void)) {
   *block();//回调执行了该block
}

在作用域内声明了一个block:

{
  //加了个`unused`的attribute来消除`unused variable`的warning
  __strong void(^block)(void) __attribute__((cleanup(blockCleanUp),unused)) = ^{
    NSLog(@"I'm dying...");
  };
}// 这里输出"I'm dying..."

Reactive Cocoa中神奇的@onExit方法,其实正是上面的写法,简单定义个宏:

#define onExit\
  __strong void(^block)(void) __attribute__((cleanup(blockCleanUp),unused)) = ^

用这个宏就能将一段写在前面的代码最后执行:

{
 onExit {
    NSLog(@"test");
 };
}//输出"test"

示例:

NSRecursiveLock *aLock = [[NSRecursiveLock alloc] init];
[aLock lock];
//这里有无数行代码
  //
   //
[aLock unlock];//看到这早已忘了和哪个lock对应了

用了onExit 之后代码更集中了:

NSRecursiveLock *aLock = [[NSRecursiveLock alloc] init];
[aLock lock];
onExit {
    [aLock unlock];//这时无论改行代码在哪里执行都无所谓了
}

2 . __attribute__((objc_requires_super))强制子类在override一个方法的时候必须调用super。

@interface MiniEastNorth :NSObject
-(void)dateWithGirl __attribute__((objc_requires_super));
@end
等价于定义好的一个Macro:NS_REQUIRES_SUPER加了这个属性之后子类没调用super编译器是无法通过的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值