本文希望介绍一个特殊的 预处理指令 #pragma clang poison
,该指令可以实现禁止调用 performSelector:
方法的诉求
performSelector:
`performSelector:`[1] 是 ObjC
运行时提供的一套动态方法调用的入口。
比如,我们可以通过下面的方法,动态调用 self
的 name
方法
SEL aSelector = NSSelectorFromString(@"name");
[self performSelector:aSelector];
这种用法同样存在很多风险,比如,可能会出现内存泄露,可能因未做好参数校验导致崩溃。
所以,很多 APP 都希望严格控制项目对 performSelector:
的使用入口,避免随意的调用 performSelector:
产生崩溃
#pragma GCC poison
`#pragma GCC poison`[2] 是 GCC 编译器支持的一个预处理指令,可以用于移除程序中的**identifier
(标识符)**
比如,#pragma GCC poison NSLog
可以让源码出现 NSLog
相关的 identifier
(标识符) 后出现报错
image-20210221224422395
clang
编译器同样支持这种写法,同时也支持将 GCC
替换成clang
所以,我们可以使用下面的预处理指令 #pragma clang poison performSelector
禁止源码中出现 performSelector
image-20210221224642391
参考资料
[1]
performSelector:
: https://developer.apple.com/documentation/objectivec/1418956-nsobject/1418867-performselector?language=occ
[2]
#pragma GCC poison
: https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html#index-_0023pragma-GCC-poison