Clang Attributes 和 Clang 警告处理

Clang Attributes

iOS开发工作中,查看官方文档时经常见到各种系统宏定义,而定义宏时经常一堆以__attribute__(xx) 的语法格式出现,这些究竟是何方神圣,有何作用?本文摘出比较常见的,做一番解释。

__attribute__(xx)的语法格式出现,是 Clang 提供的一些能够让开发者在编译过程中参与一些源码控制的方法。

__attribute__((format(__NSString__, F, A))) 格式化字符串

可以查看 NSLog 的用法:

FOUNDATION_EXPORT void NSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2) NS_NO_TAIL_CALL;

// Marks APIs which format strings by taking a format string and optional varargs as arguments
#if !defined(NS_FORMAT_FUNCTION)
    #if (__GNUC__*10+__GNUC_MINOR__ >= 42) && (TARGET_OS_MAC || TARGET_OS_EMBEDDED)
    #define NS_FORMAT_FUNCTION(F,A) __attribute__((format(__NSString__, F, A)))
    #else
    #define NS_FORMAT_FUNCTION(F,A)
    #endif
#endif

__attribute__((deprecated(s)))版本弃用提示
在编译过程中能够提示开发者该方法或者属性已经被弃用

/** Deprecated, use initWithTimeInterval: instead. */
- (instancetype)initWithTimeIntervalSince1970:(NSTimeInterval)timeIntervalSince1970
    __attribute__((deprecated("Use initWithTimeInterval:")));

__attribute__((availability(os,introduced=m,deprecated=n, obsoleted=o,message=“” __VA_ARGS__)))指明使用版本范围
os 指系统的版本,m 指明引入的版本,n 指明过时的版本,o 指完全不用的版本,message 可以写入些描述信息。

- (void)method __attribute__((availability(ios,introduced=3_0,deprecated=6_0,obsoleted=7_0,message=“iOS3到iOS7版本可用,iOS7不能用”)));

__attribute__((unavailable(…))) 方法不可用提示

这个会在编译过程中告知方法不可用,如果使用了还会让编译失败。

__attribute__((unused))

没有被使用也不报警告

__attribute__((__warn_unused_result__))

不使用方法的返回值就会警告,目前 swift3 已经支持该特性了。oc中也可以通过定义这个attribute来支持。

__attribute__((__availability__(swift, unavailable, message=_msg)))

OC 的方法不能在 Swift 中使用。

__attribute__((cleanup(…)))作用域结束时自动执行一个指定方法

作用域结束包括大括号结束,return,goto,break,exception 等情况。这个动作是先于这个对象的 dealloc 调用的。

Reactive Cocoa 中有个比较好的使用范例,@onExit 这个宏,定义如下:

#define onExit \
    rac_keywordify \
    __strong rac_cleanupBlock_t metamacro_concat(rac_exitBlock_, __LINE__) __attribute__((cleanup(rac_executeCleanupBlock), unused)) = ^

static inline void rac_executeCleanupBlock (__strong rac_cleanupBlock_t *block) {
    (*block)();
}

这样可以在就可以很方便的把需要成对出现的代码写在一起了。同样可以在 Reactive Cocoa 看到其使用

if (property != NULL) {
        rac_propertyAttributes *attributes = rac_copyPropertyAttributes(property);
        if (attributes != NULL) {
            @onExit {
                free(attributes);
            };

            BOOL isObject = attributes->objectClass != nil || strstr(attributes->type, @encode(id)) == attributes->type;
            BOOL isProtocol = attributes->objectClass == NSClassFromString(@“Protocol”);
            BOOL isBlock = strcmp(attributes->type, @encode(void(^)())) == 0;
            BOOL isWeak = attributes->weak;

            shouldAddDeallocObserver = isObject && isWeak && !isBlock && !isProtocol;
        }
    }

可以看出 attributes 的设置和释放都在一起使得代码的可读性得到了提高。

__attribute__((overloadable))方法重载
能够在 c 的函数上实现方法重载。即同样的函数名函数能够对不同参数在编译时能够自动根据参数来选择定义的函数

__attribute__((overloadable)) void printArgument(int number){
    NSLog(@“Add Int %i”, number);
}

__attribute__((overloadable)) void printArgument(NSString *number){
    NSLog(@“Add NSString %@“, number);
}

__attribute__((overloadable)) void printArgument(NSNumber *number){
    NSLog(@“Add NSNumber %@“, number);
}

__attribute__((objc_designated_initializer))指定内部实现的初始化方法

如果是 objc_designated_initializer 初始化的方法必须调用覆盖实现 super 的 objc_designated_initializer 方法。
如果不是 objc_designated_initializer 的初始化方法,但是该类有 objc_designated_initializer 的初始化方法,那么必须调用该类的 objc_designated_initializer 方法或者非 objc_designated_initializer 方法,而不能够调用 super 的任何初始化方法。
__attribute__((objc_subclassing_restricted)) 指定不能有子类

相当于 Java 里的 final 关键字,如果有子类继承就会出错。

__attribute__((objc_requires_super))子类继承必须调用 super

声明后子类在继承这个方法时必须要调用 super,否则会出现编译警告,这个可以定义一些必要执行的方法在 super 里提醒使用者这个方法的内容时必要的。

__attribute__((const)) 重复调用相同数值参数优化返回

用于数值类型参数的函数,多次调用相同的数值型参数,返回是相同的,只在第一次是需要进行运算,后面只返回第一次的结果,这时编译器的一种优化处理方式。

__attribute__((constructor(PRIORITY)))__attribute__((destructor(PRIORITY)))

PRIORITY 是指执行的优先级,main 函数执行之前会执行 constructor,main 函数执行后会执行 destructor,+load 会比 constructor 执行的更早点,因为动态链接器加载 Mach-O 文件时会先加载每个类,需要 +load 调用,然后才会调用所有的 constructor 方法。

通过这个特性,可以做些比较好玩的事情,比如说类已经 load 完了,是不是可以在 constructor 中对想替换的类进行替换,而不用加在特定类的 +load 方法里。

Clang 警告处理

先看看这个

#pragma clang diagnostic push
#pragma clang diagnostic ignored “-Wdeprecated-declarations”
        sizeLabel = [self sizeWithFont:font constrainedToSize:size lineBreakMode:NSLineBreakByWordWrapping];
#pragma clang diagnostic pop

如果没有#pragma clang 这些定义,会报出 sizeWithFont 的方法会被废弃的警告,这个加上这个方法当然是为了兼容老系统,加上 ignored “-Wdeprecated-declarations” 的作用是忽略这个警告。通过 clang diagnostic push/pop 可以灵活的控制代码块的编译选项。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容