Clang Attributes in Open Source

这篇文章应该叫做那些开源项目中用到过的 Clang Attributes,会列出开源项目的名字和使用方式以及用例

visibility

解释

__attribute__ ((visibility("default")))

visibility 中的值可以为 default | internal | hidden | protected

该属性用于设置动态链接库中函数或者变量的可见性

我们在 C 语言中,如果想要将函数或变量限制在当前文件中,可以使用 static 关键字,但是在复杂的项目中,如果想要限制某个符号被共享库内部某些文件可以访问,而外部不可以访问泽有些困难,于是 GCC 中引入了 visibility 属性,它可以设置某个函数或变量是否可访问,例如这个变量在多个文件中被定义,又同时有多个链接库需要引用它时,如果不设置可见性,那么到底引用为那个值或者函数就要看加载顺序了。

用例

UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert;
UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar __TVOS_PROHIBITED;

#ifdef __cplusplus
#define UIKIT_EXTERN        extern "C" __attribute__((visibility ("default")))
#else
#define UIKIT_EXTERN            extern __attribute__((visibility ("default")))
#endif

项目

JDStatusBarNotification

参考文献

Visibility Pragmas
Controlling Symbol Visibility

objc_subclassing_restricted

解释

__attribute__((objc_subclassing_restricted))

用于限制某个类是不可继承的,但是这个限制只是编译时的限制,不直接写 @interface SubClass : ParentClass,而是使用 Runtime 的方式仍然是可以创建继承关系的。

void run(id self, SEL _cmd) {}
class subClass = objc_allocateClassPair([ParentClass class], "SubClass", 0);
class_addMethod(subClass, @selector(run),(IMP) run, "v@:");
objc_registerClassPair(subClass);

用例

__attribute__((objc_subclassing_restricted))
@interface ParentClass : NSObject
@end
@interface SubClass : ParentClass // <--- Compile Error
@end

参考文献

Clang Attributes 黑魔法小记

deprecated

解释

__attribute__((deprecated("弃用解释说明")));

用于说明某个属性已经弃用

@property (assign, nonatomic) CGFloat opacity __attribute__((deprecated("Customize bezelView properties instead.")));

用例

另外,忽略弃用警告可以使用

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
self.bezelView.alpha = self.opacity;
#pragma clang diagnostic pop

项目

MBProgress

objc_requires_super

解释

子类可以覆盖父类方法,如果子类需要调用父类方法使用 super 父类方法名,如果需要强制子类调用父类的方法,可以使用 objc_requires_super,当子类没有调用父类方法时则会给出警告

示例

@interface Father : NSObject
- (void)payMoney __attribute__((objc_requires_super));
@end
@implementation Father
- (void)payMoney {
    NSLog(@"I paid");    
}
@end
@interface Son : Father
@end
@implementation Son
- (void)payMoney {
} // <--- Compile Error Missing call [super payMoney]
@end

// .. 待追加

名称

解释

用例

项目

示例

参考文献

请我喝汽水儿