attribute 编译指令

attribute 一个用于在声明时指定一些特性的编译器指令,它可以开启很多额外的错误检查和高级优化工作。在 GCC 和 LLVM 中都有支持

它的语法格式通常为 __attribute__((command)),参数部分的两个括号是为了便于在宏里面使用。
GCC 和 LLVM 中支持的编译属性并不完全一致,如果要检查能否使用特定的属性,可以用 __has_attribute 这个指令

下面列举一些常用的编译指令

availability

可用性属性,放在声明之后表示该声明在系统版本上的支持情况

constructor / destructor

构造器和析构器声明,有这两个声明的函数会在分别在可执行文件(或 shared library)loadunload 时被调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
__attribute__((constructor))
static void load(void) {
NSLog(@"load ...");
}
__attribute__((destructor))
static void unload(void) {
NSLog(@"unload ...");
}
int main(int argc, const char * argv[]) {
NSLog(@"main");
return 0;
}

// result: "load" -> "main" -> "unload"

cleanup

用于修饰一个变量,在它的作用域结束时可以自动执行一个指定的方法。这个声明符号可以在 OC 中实现 Swift 中的 defer

objc_runtime_name

@interface@protocol 的声明符,可以将类或协议的名字在编译时替换

1
2
3
__attribute__((objc_runtime_name("AnotherName")))
@interface NormalClass: NSObject
@end

objc_subclassing_restricted

组织类被继承的属性,可以通过这个属性实现 Final Class

1
2
3
4
5
6
7
#define Final __attribute__((objc_subclassing_restricted))

Final @interface FinalClass: NSObject
@end

@interface ChildClass : FinalClass // Error: Cannot subclass a class that was declared with the 'objc_subclassing_restricted' attribute
@end

objc_requires_super

就是 NS_REQUIRES_SUPER 宏,子类重写这个属性声明的方法时必须调用 super

1
- (void)mustSuperMethod NS_REQUIRES_SUPER;

objc_boxable

ObjC 中的 @(...) 语法糖可以将基本数据类型装箱包装成 NSNumber 对象,实质上就是使用类 objc_boxable 声明可以装箱的属性,利用这一特性,我们可以将更多的数据类型添加到可以使用这一语法糖的行列中

1
2
3
4
5
6
typedef struct __attribute__((objc_boxable)) {
CGFloat x, y, width, height;
} BoxRect;

BoxRect rect = {1, 2, 3, 4};
NSValue *value = @(rect2); // 将自定义的 Rect 装箱为 NSValue

overloadable

Clang 在 C 语言中提供了 C++ 函数重载支持,通过 __attribute__((overloadable)) 声明可以实现函数重载;只能用于 C 函数

1
2
3
4
#define Overload __attribute__((overloadable))

Overload NSString *overloadFunc(NSString *argu) {return argu;}
Overload NSString *overloadFunc(NSNumber *argu) {return [NSString stringWithFormat:@"%@", argu];}

参考

Clang attribute

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2017-2021 HonQi

请我喝杯咖啡吧~