语法
一般以attribute后面加参数
__attribute__(xx)
整理一下常用的,如下。
1、deprecated
在编译时会报过时警告
__attribute__((deprecated("使用#method2")));- (void)method12 DEPRECATED_ATTRIBUTE;//DEPRECATED_ATTRIBUTE是系统的宏
2、unavailable
NS_UNAVAILABLE、UNAVAILABLE_ATTRIBUTE、__attribute__((unavailable("不能用,不能用,不能用")));
3、cleanup
- (void)cleanupDemo {
NSObject *myVar __attribute__((cleanup(cleanUpCallback))) = [[NSObject alloc] init];
NSLog(@"%@",xcode);
}
// 指定一个cleanup方法,注意入参是所修饰变量的地址,类型要一样
// 对于指向objc对象的指针(id *),如果不强制声明__strong默认是__autoreleasing,造成类型不匹配
static void cleanUpCallback(__strong NSObject **xcode){
NSLog(@"cleanUp call %@",*xcode);
}
4、availability 、unavailable
__attribute__((availability(ios,introduced=2_0,deprecated=3_0,message=""__VA_ARGS__)))
//系统的宏,可以直接拿来用#defineUNAVAILABLE_ATTRIBUTE __attribute__((unavailable))#defineNS_UNAVAILABLE UNAVAILABLE_ATTRIBUTE
5、overloadable
这个属性用在C的函数上实现像java一样方法重载。直接上主菜:
__attribute__((overloadable))
void add(int num) {
NSLog(@"Add Int %i",num);
}
__attribute__((overloadable))
void add(NSString* num) {
NSLog(@"Add NSString %@",num);
}
__attribute__((overloadable))
void add(NSNumber* num) {
NSLog(@"Add NSNumber %@",num);
}
6、 objc_designated_initializer
NS_DESIGNATED_INITIALIZER、__attribute__((objc_designated_initializer))
7、objc_subclassing_restricted
这个顾名思义就是相当于java的final关键字了,意是说它不能有子类。用于类
__attribute__((objc_subclassing_restricted))//Final类 ,java的final关键字@interfaceCustomObject:NSObject
8、objc_requires_super
这个也挺有意思的,意思是子类重写这个方法的时候,必须调用[super xxx]
#define NS_REQUIRES_SUPER __attribute__((objc_requires_super))
- (void)method __attribute__((objc_requires_super));
9、nonnull
__attribute__((nonnull(1,2)))
10、objc_boxable
实现类似于NSNumber 的快速打包能力@(...),一般对于struct,union我们只能通过NSValue将其打包. objc_boxable 可以帮助我们实现快速打包,示例如下:
//自定义结构体
typedef struct __attribute__((objc_boxable)) {
CGFloatx,y,width,height;
}SGRect;
SGRect rect = {0,0,100,200};
//这里直接打包成
NSValue NSValue *value = @(rect);
//这里我直接用系统的方法打印NSLog(@"%@",NSStringFromCGRect(value.CGRectValue));
输出:2016-07-2121:28:43.538Study[14118:5408921] {{0,0}, {100,200}}
11、constructor / destructor
意思是: 构造器和析构器;constructor修饰的函数会在main函数之前执行,destructor修饰的函数会在程序exit前调用.
__attribute__((constructor))voidbefore(){NSLog(@"before main");}
__attribute__((destructor))voidafter(){NSLog(@"after main");}
12、enable_if
用来检查参数是否合法,只能用来修饰函数:
void printAge(int age) __attribute__((enable_if(age >0&& age <120," 0 ~ 120"))) {
NSLog(@"%d",age);
}
表示只能输入的参数只能是 0 ~ 120左右,否则编译报错
13、objc_runtime_name
看到runtime是不是就感觉高大上,没错这个也跟运行时有关.作用是将将类或协议的名字在编译时指定成另一个.示例如下:
__attribute__((objc_runtime_name("NSObject")))
@interface SGObject:NSObject
@end
//调用NSLog(@"%@",[SGObject class]);
//输出2016-07-2211:18:00.934 Study[14355:5516261] NSObject
14、objc_root_class
表示这个类是一个根类(基类),比如NSObject,NSProxy.
//摘自系统
//NSProxy
NS_ROOT_CLASS
@interface NSProxy{
Class isa;
}
//
NSObject
__OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_2_0)
OBJC_ROOT_CLASS
OBJC_EXPORT
@interface NSObject {
Class isa OBJC_ISA_AVAILABILITY;
}
15、warn_unused_result
当函数或者方法的返回值很重要时,要求调用者必须检查或者使用返回值,否则编译器会发出警告提示
- (BOOL)availiable __attribute__((warn_unused_result)) {
return 10;
}
文章引用:iOS中常用的Attribute
http://nshipster.com/__attribute__/
http://releases.llvm.org/3.8.0/tools/clang/docs/AttributeReference.html