gpt4 book ai didi

objective-c - 我们可以确保 `+ (nonnull instancetype)sharedInstance;` 的可空性吗?

转载 作者:太空狗 更新时间:2023-10-30 03:43:45 25 4
gpt4 key购买 nike

这是一个关于如何优雅地规避 NSObject 类中的 init 可空性的问题。

这是一个经典的 Objective-C 实现:

+ (instancetype)sharedInstance
{
static dispatch_once_t onceToken;
static id sharedInstance;
dispatch_once(&onceToken, ^
{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}

但现在我想将其声明为 nonnull,如果可能的话:

+ (nonnull instancetype)sharedInstance;

不幸的是,init 返回一个 nullable instancetype 值。我应该在调用 init 之后添加一个 NSAssert 还是什么?

我注意到有些人甚至 document nonnull values as being in reality nullable .这有意义吗?

我是否应该大胆地在任何地方简单地添加 NS_ASSUME_NONNULL_BEGIN,而不真正确保值是 nonnull

最佳答案

这里好像有两个问题:

  1. 如何确保在我的单例 sharedInstance 方法中产生并由该方法返回的值在运行时实际上不是 nil?

  2. 我如何满足可空性注释、编译器警告和 Swift 桥接的系统要求我返回一个 nonnull 指针?

确保/强制执行nonnull

在某些时候,每个 API 契约(Contract)都会分解为人工契约(Contract)。编译器可以帮助确保,例如,您不能获取 nullable 调用的结果并从返回类型为 nonnull 的方法返回它...但是某处通常有一个返回类型为 nonnull 的原始调用,这仅仅是因为编写它的程序员说,“我保证永远不会返回 null,我很伤心,等等。”

如果您熟悉 Swift,这类似于隐式解包选项的情况——当您“知道”一个值不能为 nil 时使用它们,但无法向编译器证明该知识,因为该知识在源代码之外(例如,来自 Storyboard或捆绑资源的东西)。

这就是这里的情况——你“知道”init 永远不会返回 nil,要么是因为你写了/有相关初始化程序的源代码,要么是因为它只是 NSObjectinit 被记录为 return self 而不做任何事情。对该初始化程序的调用失败的唯一情况是因为前面的 alloc 调用失败(因此您在 nil 上调用一个方法,它总是返回 )。如果 alloc 返回 nil,那么你已经在 dire straits 中了并且您的流程对于这个世界来说并不长 — 这不是围绕设计 API 的失败案例。

(可空性注释通常用于描述 API 的预期用途,而不是更极端的极端情况。如果 API 调用仅因为 universal error 而失败,则将其注释为可空性没有意义;同样,如果API 仅在可以通过非空参数注释排除的输入上失败,返回值可以假定为非空。)

所以,长话短说:是的,只需将 NS_ASSUME_NONNULL 放在您的标题周围,然后按原样发送您的 sharedInstance 实现。

返回一个可空的nonnull

这里不是这种情况,但假设您有一个注释为 nullable 的值,但您知道(或“知道”)它永远不会为 nil 并且想从您的 nonnull - 注释方法。并且您遇到了尝试时收到编译器警告的情况。

有一个语法——只需将值转换为预期的返回类型、注释和所有:

return (NSWhatever *_Nonnull)whatever;

在你的情况下,这不应该是必需的——因为你正在处理 idinstancetype 特殊类型,编译器对可空性转换更宽容并且可能会赢'警告开始。

关于objective-c - 我们可以确保 `+ (nonnull instancetype)sharedInstance;` 的可空性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34195149/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com