__attribute__
是什么? __attribute__
是Clang提供的、用来在C,C++和Objective-C中修饰代码定义的 编译指令 。它为声明的代码提供了额外的属性,来帮助编译器优化或者为代码的使用者显示有用的警告信息。
__attribute__
有什么用? __attribute__
命令提供代码运行需要的上下文。提供上下文的重要性怎么强调都不过分。通过详细地给出API如何命令编译器的定义,开发者可以获得显而易见的益处。同样是一束鲜花,是要在情人节送给女朋友还是要用来探望术后的病人,效果是完全不同的。而 __attribute__
的作用就好像鲜花上附加的一张卡片,上面写的是“送给最爱的某某”还是“愿某某早日康复”是完全由你来决定的。
正如Mattt在 这里 指出的:
当涉及到编译器优化时,上下文就是王道。通过约束你的代码的解释方式,你可以让生成的代码尽可能的高效。不只是为了编译器。下一个看代码的人也会感激(你所提供的)额外的上下文信息。
__attribute__
怎么用? 它的语法是这样的: __attribute__((interrupt(“TYPE")))
。
每当你有机会来给代码定义(变量,参数,函数,方法,类等等)提供额外的上下文信息时,你都应该使用 __attribute__
。但除非你知道自己在干什么,否则,不要滥用。因为提供一个错误的上下文比没有提供上下文更糟糕。
__attribute__
使用举例? #define NS_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios) #define CF_AVAILABLE(_mac, _ios) __attribute__((availability(macosx,introduced=_mac)))
在 Foundation
库的 NSString.h
中的使用:
- (BOOL)containsString:(NSString *)str NS_AVAILABLE(10_10,8_0);
#define NS_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, __VA_ARGS__) #define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) __attribute__((availability(macosx,introduced=_macIntro,deprecated=_macDep,message="" __VA_ARGS__)))
同样在 Foundation
库的 NSString.h
中:
- (nullable id)initWithContentsOfFile:(NSString *)path NS_DEPRECATED(10_0, 10_4, 2_0, 2_0);(用带有encoding/usedEncoding和error参数的方法替代)
在 Foundation
库的 NSObjCRuntime.h
中:
FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2) NS_NO_TAIL_CALL; #define NS_FORMAT_FUNCTION(F,A) __attribute__((format(__NSString__, F, A)))
语法说明: __attribute__((format(format_type, format_string_index, first_format_argument_index))) format_type: one of printf, scant, strftime, strfmon or __NSString__
在 Foundation
库的 NSObjcRuntime.h
中:
#ifndefNS_REQUIRES_SUPER// 防止头文件的重复包含和编译。 #if__has_attribute(objc_requires_super) #defineNS_REQUIRES_SUPER __attribute__((objc_requires_super)) #else #defineNS_REQUIRES_SUPER #endif #endif
比如在自定义的 @interface Student: NSObject
中声明了:
- (void)foo NS_REQUIRES_SUPER;
那么在 @interface CollegeStudent: Student
的实现文件中,像这样写一个空的 -foo
函数是会报出警告的:
- (void)foo { } warning: Methodpossiblymissinga[superfoo]call
总而言之,当你想给自己写的类、方法、参数添加一些限制条件的时候, __attribute__
可以为你提供一种可行的解决方案。