【问题标题】:Recipes on how to supress / fix "Implicit conversion changes signedness" warning有关如何抑制/修复“隐式转换更改签名”警告的食谱
【发布时间】:2015-03-12 16:27:42
【问题描述】:

我正在对遗留项目进行现代化改造,并在 Xcode 上启用了-Wconversion 标志。现在我有很多警告,比如

隐式转换改变签名:'NSUInteger'(又名'unsigned long') 到 'NSInteger' (又名'long')

在与UITableView 交互时使用如下代码

Item *item = [self.items objectAtIndex:indexPath.row];

row 被定义为NSInteger,而objectAtIndex: 接受NSUInteger

有解决这些警告的聪明方法吗?

【问题讨论】:

    标签: objective-c xcode compiler-warnings


    【解决方案1】:

    要么将row 属性的类型更改为返回NSUInteger,要么执行以下操作:

    Item *item = [self.items objectAtIndex:(NSUInteger)(indexPath.row)];
    

    如果您选择后者,您可能需要检查以确保 row 是肯定的。


    编辑

    由于rowNSIndexPath 的属性,显然有充分的理由说明它可能为负数,否则Apple 会将其设为NSUInteger,也许如果没有选择任何项目,则将其设置为- 1.所以你应该做的是确保 row 的值不是负数,然后执行上面的强制转换以抑制警告,如下所示:

    NSInteger row = indexPath.row
    if (row >= 0)
    {
        Item *item = [self.items objectAtIndex:(NSUInteger)row];
    }
    else
    {
        // whatever you need to do for no row available
    }
    

    【讨论】:

    • 是的!演员阵容是正确的,但我想我会发疯的。 row 属性的类型更改为返回NSUInteger 是什么意思?在这种情况下,row 属于 NSIndexPath 类。
    • 那么,您的项目中是否启用了-Wconversion
    • @flexaddicted 稍微修改了答案
    • 谢谢。您在项目中使用 -Wconversion 吗?想知道。是的。演员表是更简单的解决方案,但我想我会使用 clang push/pop 调用来跳过这些警告。
    • @flexaddicted 是的,我总是打开那个。它们确实表明您的代码存在真正的潜在问题。如果row 属性为负数,则会出现数组边界异常。
    【解决方案2】:

    通常你不应该试图变得“聪明”。

    NSUInteger row = (NSUInteger)indexPath.row;
    Item* item = self.items [row];
    

    【讨论】:

    • 是的!演员阵容是正确的,但我想我会发疯的。
    • 那么,您的项目中是否启用了-Wconversion
    • 警告在这里是有原因的。如果像indexPath.row < self.items.count-1这样比较,而items.count为0,右边的无符号整数会默默下溢(变成NSUIntegerMax),所以比较的结果会出乎你的意料。由于这个微妙的错误,我浪费了我的生命中的几个小时,之后我总是打开这个警告。你可以看看我的问题:stackoverflow.com/q/21724824/2128900
    【解决方案3】:

    升级到 Xcode 11 后,我不断收到此警告。 回到 Xcode 10 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-13
      相关资源
      最近更新 更多