您的位置:首页 > 移动开发 > IOS开发

iOS 黑魔法 __attribute__(转摘)

2015-07-17 14:48 781 查看
原文地址http://blog.sunnyxx.com/2014/09/15/objc-attribute-cleanup/#rd

关于
__attribute__
的更详细的用法可以参考这一篇/article/2554100.html

__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编译器是无法通过的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: