Xcode 9.2更新后assert用字符串字面量触发警告,求替代方案
解决Xcode 9.2中assert使用OC字符串字面量的警告问题
嘿,这个问题我太熟悉了!Xcode 9.2强化了对隐式类型转换的检查,你遇到的警告本质上是在提醒你:原来的assert(@"Must be implemented by subclass");写法逻辑是有问题的——Objective-C字符串字面量是一个非nil对象,转换成布尔值永远为true,所以这个断言永远不会被触发,完全起不到你想要的“检查子类是否实现方法”的作用。
下面给你几个靠谱的替代方案,按推荐程度排序:
1. 使用OC专属的NSAssert(最推荐)
NSAssert是苹果专门为Objective-C环境设计的断言宏,完美适配OC的语法,不会有类型转换问题。把你的代码改成:
NSAssert(NO, @"Must be implemented by subclass");
- 解释:
NSAssert的第一个参数是布尔条件,当条件为NO时触发断言;第二个参数是格式化字符串,用来输出错误信息。 - 优势:符合OC开发的规范,错误信息清晰,默认在Debug模式下生效,Release模式会自动被移除(可以通过设置编译选项修改)。
2. 修正标准C的assert写法(如果坚持用C断言)
如果你习惯用标准C的assert,需要把字符串转换成一个永远为false的布尔表达式,比如:
assert(!"Must be implemented by subclass");
或者更直观的:
assert(0 && @"Must be implemented by subclass");
- 解释:
!"xxx"会把字符串字面量转换成布尔值true后取反,得到false,这样断言会正常触发;0 && ...因为逻辑与的短路特性,表达式结果永远是0(false),同时字符串会作为表达式的一部分出现在断言错误信息里。 - 注意:标准C的
assert在Release模式下会被完全编译掉,如果你需要Release环境下也保留检查逻辑,这个方案不适用。
3. 直接抛出异常(针对必须保证子类实现的场景)
如果这个方法是子类必须强制实现的核心方法,断言可能不够严格,可以直接抛出异常:
[NSException raise:NSInternalInconsistencyException format:@"Must be implemented by subclass"];
- 解释:这个方法会直接终止程序并抛出明确的异常信息,不管是Debug还是Release模式都会生效,适合那些不允许子类不实现的关键方法。
最后再强调一下:原来的写法不仅会触发警告,更重要的是它根本不会起到断言的作用——因为assert(@"xxx")永远为true,断言永远不会触发,等于白写了。Xcode的警告其实是在帮你发现这个隐藏的逻辑错误哦!
内容的提问来源于stack exchange,提问作者Francis F
相关产品推荐
相关产品推荐

