0

最近我打开CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION了 Xcode,但我的 Objective-C 代码中出现了与可空性相关的警告,让我不知所措。最普遍的一种警告类型是Implicit conversion from nullable pointer 'TypeA * _Nullable' to non-nullable pointer type 'TypeA * _Nonnull'.

我开始尝试通过在此处描述的方法中创建相同类型的本地来删除这些警告。 https://www.mail-archive.com/xcode-users%40lists.apple.com/msg02260.html 这篇文章说首先使用本地,该对象的属性未指定可以为空,因此可以用作合法参数到期望非空的方法。

但我觉得这是一种逃避行为,实际上并没有以任何有益的方式解决问题。

有人做过这个练习吗?如果您能分享您采取的策略,我将不胜感激。

4

2 回答 2

1

并非每个警告都有意义。有时这是编译器的一个缺点。例如,此代码不需要警告。

- (nullable id)transformedValue:(nullable id)value {
    id result = value != nil ? UIImageJPEGRepresentation(value, 1.0) : nil;
    return result;
}

我们正在检查它是否为空!我们还能做什么?为什么要创建一个额外的指针?

所以,我们这样做:

- (nullable id)transformedValue:(nullable id)value {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnullable-to-nonnull-conversion"
    id result = value != nil ? UIImageJPEGRepresentation(value, 1.0) : nil;
#pragma clang diagnostic pop
    return result;
}

为什么这是正确的答案?

首先,比编译器更聪明是可以的。你不想仅仅因为一个虚假的警告就开始破坏你的代码。

此解决方案指定要抑制的确切警告消息,并且仅抑制一行。

于 2017-02-16T09:04:54.033 回答
1

实际上,我已经把这个话题搞砸了一点。我想在一个有点大的项目中改善可空性情况(让它更“迅速”)。这是我发现的。

首先,您应该打开CLANG_WARN_NULLABLE_TO_NONNULL_CONVERSION( -Wnullable-to-nonnull-conversion)

其次,关于

首先使用本地对象,该对象的属性未指定可为空,因此它可以用作期望非空的方法的合法参数。

这闻起来很糟糕,我创建了一个名为NONNUL_CAST(). 以下是如何实现它的示例:

#define NONNUL_CAST(__var) ({ NSCAssert(__var, @"Variable is nil");\
    (__typeof(*(__var))* _Nonnull)__var; })

在这里你可以看到 hacky __typeof(*(__var))* _Nonnull)__var,但还不错。如果__varA* _Nullable我们取消引用__var的类型,那么它现在只是类型A,在我们再次引用之后,但是_Nonnull,并得到非空__var作为答案。当然,我们断言,以防万一出现问题。

第三,您必须在每个局部变量上指定可空性,并且应该将所有代码放入 中NS_ASSUME_NONNULL_BEGIN/END,如下所示:

NS_ASSUME_NONNULL_BEGIN 
<your_code_goes_here>
NS_ASSUME_NONNULL_END`

您将代码的每一行(导入除外)放在.h.m文件中。这将假定您的方法、返回类型和属性的所有参数都是非空的。如果你想让它可以为空,把它放在那里。

那么,一切都完成了,现在呢?以下是典型用法示例:

- (Atype*)makeAtypeWithBtype:(nullable BType*)btype {
  Atype* _Nullable a = [btype makeAtype];
  if (a) {
    // All good here.
    return NONNUL_CAST(a);
  } else {
    // a appeared as nil. Some fallback is needed.
    [self reportError];
    return [AtypeFactory makeDeafult];
  }
}

现在您有了更强大的可空性情况。可能看起来不太好看,但它是客观的,所以没什么可抱怨的。

于 2016-09-14T23:03:16.903 回答