Clang 命令
1、將.m文件轉(zhuǎn)成.cpp略水,由oc轉(zhuǎn)成c++森瘪,方便查看大概的源碼實現(xiàn)。
clang -rewrite-objc xxx.m (xxx指文件名)
如果報錯吵血,例如 fatal error: 'UIKit/UIKit.h' file not found谎替,可用以下命令代替
clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk xxx.m
Clang Attributes
2、objc_subclassing_restricted
定義不可繼承的類
__attribute__((objc_subclassing_restricted))
@interface MyCar : NSObject
@end
3蹋辅、objc_requires_super
子類繼承父類方法時钱贯,必須調(diào)用super,否則產(chǎn)生警告侦另。
@interface Father : NSObject
- (void)playGame __attribute__((objc_requires_super));
@end
@implementation Father
- (void)playGame {
NSLog(@"play cs");
}
@end
@interface Son : Father
@end
@implementation Son
- (void)playGame {
} //warning missing [super playGame]
@end
4秩命、objc_boxable
可用語法糖將struct或者union類型裝箱成NSValue對象
typedef struct __attribute__((objc_boxable)) {
CGFloat x, y, width, height;
} XXRect;
XXRect rect = {1, 2, 3, 4};
NSValue *value = @(rect);
5、constructor / destructor
構(gòu)造器和析構(gòu)器褒傅,分別在可執(zhí)行文件load和unload時被調(diào)用弃锐,constructor比load晚,比main函數(shù)早殿托。
可有多個constructor霹菊, attribute((constructor(101))),數(shù)字越小優(yōu)先級越高支竹,1 ~ 100 為系統(tǒng)保留旋廷。
__attribute__((constructor))
static void beforeMain(void) {
NSLog(@"beforeMain");
}
__attribute__((destructor))
static void afterMain(void) {
NSLog(@"afterMain");
}
int main(int argc, const char * argv[]) {
NSLog(@"main");
return 0;
}
// 輸出: beforeMain -> main -> afterMain
6、enable_if
只能用在 C 函數(shù)上礼搁,可以用來實現(xiàn)參數(shù)的靜態(tài)檢查:
static void test(int a)
__attribute__((enable_if(a > 0 && a < 10, "不在此范圍內(nèi)"))) {
printf("%d", a);
}
7饶碘、cleanup
用來聲明變量,當此變量作用域結(jié)束時馒吴,調(diào)用指定的C方法扎运。
static void callback(__strong NSString **string) {
NSLog(@"%@", *string);
}
{
//該變量作用域,作用域結(jié)束時調(diào)用callback
__strong NSString *string __attribute__((cleanup(callback))) = @"abc";
}
執(zhí)行輸出: abc
8饮戳、overloadable
用于 C 函數(shù)豪治,可以定義若干個函數(shù)名相同,但參數(shù)不同的方法莹捡,調(diào)用時編譯器會自動根據(jù)參數(shù)選擇函數(shù)原型:
__attribute__((overloadable)) void testMan(int number) {
NSLog(@"%@", @(number));
}
__attribute__((overloadable)) void testMan(id obj) {
NSLog(@"%@", obj);
}
__attribute__((overloadable)) void testMan(CGRect rect) {
NSLog(@"%@", NSStringFromCGRect(rect));
}
testMan(@"123");
testMan(234);
testMan(CGRectMake(1, 2, 3, 4));
9鬼吵、objc_runtime_name
將類或協(xié)議的名字在編譯時指定成另一個,常用在代碼混淆篮赢。
__attribute__((objc_runtime_name("MyCar")))
@interface MyBike : NSObject
@end
NSLog(@"%@", NSStringFromClass([MyBike class])); // "MyCar"