新瓶装老酒,用宏来快速消除Xcode警告

当我们没有新需求时,就会手痒痒要消除项目中的警告,即不会太无聊,又不会让boss觉得你很闲😂。
如何消除Xcode警告,想必大家见过不少文章了。总结起来,大体上有以下几种方法:

1:编译器警告的代码确实有问题,那就修改代码消除。
2:代码中使用 #pragma 预编译指令消除指定类型的警告。
3:在Compile Sources列表中,对某个文件添加消除指定警告的CompileFlags
4:使用cocoapods管理时可以指定消除全部的警告或者指定消除某个库的警告。
5:在Build Setting中搜索Warning,可以通过各个警告类型的开关,来控制全局的警告提示。

今天在这里研究第二种方法,通过宏:

NO_WARNING_BEGIN(-Wundeclared-selector)
NO_WARNING_END

来代替如下长长的预编译指令。

#pragma clang diagnostic push
#pragma clang diagnostic ignored -Wunused-function
//code
#pragma clang diagnostic pop

先亮宏定义:

// 这几个宏不要直接使用
#define N_W_MACRO_CAT(a,b)  a b
#define N_W_MACRO_STR_(text) # text
#define N_W_MACRO_STR(text) N_W_MACRO_STR_(text)
#define N_W_MACRO_PREFIX_   clang diagnostic ignored
#define N_W_MACRO_PREFIX    N_W_MACRO_PREFIX_
#define N_W_MACRO_(text)    N_W_MACRO_CAT(N_W_MACRO_PREFIX,N_W_MACRO_STR(text))
#define N_W_MACRO(text)     N_W_MACRO_STR(N_W_MACRO_(text))

//下面就是消除警告开始宏
#define NO_WARNING_BEGIN(text)\
    _Pragma("clang diagnostic push")\
    _Pragma(N_W_MACRO(text))
//下面就是结束消除警告宏
#define NO_WARNING_END \
    _Pragma("clang diagnostic pop")

使用方法:

// 使用消除警告宏消除警告
NO_WARNING_BEGIN(-Wunused-function)
NO_WARNING_BEGIN(-Wundeclared-selector)
NO_WARNING_BEGIN(-Warc-performSelector-leaks)

// 不消除警告时,Xcode会在这一行显示警告:Unused function 'test2'
static void test2(void){
  id obj = [NSObject new];
  // 不消除警告时,Xcode会在这一行显示警告:Undeclared selector 'theSELName'
  SEL aSEL = @selector(theSELName);
  if ([obj respondsToSelector:aSEL]) {
    // 不消除警告时,Xcode会在这一行显示警告:PerformSelector may cause a leak because its selector is unknown
    [obj performSelector:aSEL];
  }
}
//警告结束,后面的代码可以继续出现警告
NO_WARNING_END

原理就是:使用 _Pragma 代替 #pragma。通过一系列字符拼接将两行预编译指令压缩到一个宏中。
有人会问了,这样做有什么好处呢?也就少了一行代码而已。😬
那么我就说一个好处:宏有代码提示😝,仅此而已。大家把常用的警告类型也做成宏,那就括号内的内容也有提示了。

附上源码:

//
//  Warning.h
//  CDT
//
//  Created by wwwbbat on 2017/7/6.
//  Copyright © 2017年 . All rights reserved.
//

#ifndef Warning_h
#define Warning_h

// 不要修改下面的宏
#define N_W_MACRO_CAT(a,b)  a b
#define N_W_MACRO_STR_(text) # text
#define N_W_MACRO_STR(text) N_W_MACRO_STR_(text)
#define N_W_MACRO_PREFIX_   clang diagnostic ignored
#define N_W_MACRO_PREFIX    N_W_MACRO_PREFIX_
#define N_W_MACRO_(text)    N_W_MACRO_CAT(N_W_MACRO_PREFIX,N_W_MACRO_STR(text))
#define N_W_MACRO(text)     N_W_MACRO_STR(N_W_MACRO_(text))

#define NO_WARNING_BEGIN(text)\
    _Pragma("clang diagnostic push")\
    _Pragma(N_W_MACRO(text))


#define NO_WARNING_END \
    _Pragma("clang diagnostic pop")

// 不要修改上面的宏

// 用法与示例

// 请将 WARNING_DEMO 设为 1 打开示例
#define WARNING_DEMO 0

#if DEBUG && WARNING_DEMO

/*
 正常情况下,test1会有三个警告:
 a: Unused function 'test1'
 b: Undeclared selector 'theSELName'
 c: PerformSelector may cause a leak because its selector is unknown

 按 command + 5 打开警告列表。找到a,b,c对应的警告,右键选择 Reveal in log。
 可以看到这样的文本:
 Common/Warning.h:51:17: warning: undeclared selector 'theSELName' [-Wundeclared-selector]
 SEL aSEL = @selector(theSELName);
 ^
 /Users/jay/iOS/CDT/CDT/CDT2017/Common/Warning.h:54:14: warning: performSelector may cause a leak because its selector is unknown [-Warc-performSelector-leaks]
 [obj performSelector:aSEL];
 ^
 Common/Warning.h:48:13: warning: unused function 'test1' [-Wunused-function]
 static void test1(void){
 ^
 其中可以找到
 a 的警告类型:-Wunused-function
 b 的警告类型:-Wundeclared-selector
 c 的警告类型:-Warc-performSelector-leaks

 在发出警告的代码前使用消除警告代码宏即可消除这些警告。
 忘了在消除了警告的代码之后使用结束宏。消除开始宏可以写多个。结束宏只需要写一个就可以使得结束宏后面的代码的警告再次出现。

 你也可以在 http://fuckingclangwarnings.com 找到这些警告列表
 */

// 这个函数没有消除警告
static void test1(void){
    id obj = [NSObject new];
    SEL aSEL = @selector(theSELName);
    if ([obj respondsToSelector:aSEL]) {
        [obj performSelector:aSEL];
    }
}

// 使用消除警告宏消除警告
NO_WARNING_BEGIN(-Wunused-function)
NO_WARNING_BEGIN(-Wundeclared-selector)
NO_WARNING_BEGIN(-Warc-performSelector-leaks)

// 不消除警告时,Xcode会在这一行显示警告:Unused function 'test2'
static void test2(void){
    id obj = [NSObject new];
    // 不消除警告时,Xcode会在这一行显示警告:Undeclared selector 'theSELName'
    SEL aSEL = @selector(theSELName);
    if ([obj respondsToSelector:aSEL]) {
        // 不消除警告时,Xcode会在这一行显示警告:PerformSelector may cause a leak because its selector is unknown
        [obj performSelector:aSEL];
    }
}
NO_WARNING_END

#endif

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

推荐阅读更多精彩内容