Clang 命令
1、將.m文件轉(zhuǎn)成.cpp,由oc轉(zhuǎn)成c++,方便查看大概的源碼實(shí)現(xiàn)。
clang -rewrite-objc xxx.m (xxx指文件名)
如果報(bào)錯(cuò),例如 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
子類繼承父類方法時(shí),必須調(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
可用語(yǔ)法糖將struct或者union類型裝箱成NSValue對(duì)象
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時(shí)被調(diào)用,constructor比load晚,比main函數(shù)早。
可有多個(gè)constructor, attribute((constructor(101))),數(shù)字越小優(yōu)先級(jí)越高,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ù)上,可以用來(lái)實(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
用來(lái)聲明變量,當(dāng)此變量作用域結(jié)束時(shí),調(diào)用指定的C方法。
static void callback(__strong NSString **string) {
NSLog(@"%@", *string);
}
{
//該變量作用域,作用域結(jié)束時(shí)調(diào)用callback
__strong NSString *string __attribute__((cleanup(callback))) = @"abc";
}
執(zhí)行輸出: abc
8、overloadable
用于 C 函數(shù),可以定義若干個(gè)函數(shù)名相同,但參數(shù)不同的方法,調(diào)用時(shí)編譯器會(huì)自動(dòng)根據(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é)議的名字在編譯時(shí)指定成另一個(gè),常用在代碼混淆。
__attribute__((objc_runtime_name("MyCar")))
@interface MyBike : NSObject
@end
NSLog(@"%@", NSStringFromClass([MyBike class])); // "MyCar"