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

2024-03-14

这是一个关于如何优雅地规避可空性的问题init in NSObject class.

这是一个经典的 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价值。我应该添加一个NSAssert或者打电话后的事情init?

我注意到有些人甚至文档nonnull现实中的价值观nullable https://github.com/LaunchKit/launchkit-ios/blob/1.1.2/LaunchKit/Classes/LaunchKit.h。那有意义吗?

我应该大胆地添加NS_ASSUME_NONNULL_BEGIN无处不在,但没有真正确保价值观nonnull?


这里似乎有两个问题:

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

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

确保/执行nonnull

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

如果您熟悉 Swift,这与隐式解包选项的情况类似——当您“知道”某个值不能为 nil,但无法向编译器证明该知识时,您可以使用这些选项,因为该知识是外部的源代码(例如,来自情节提要或捆绑资源的内容)。

这就是这里的情况——你“知道”init永远不会返回 nil,要么是因为您编写/有相关初始化程序的源代码,要么是因为它只是NSObject's init其记录为return self不做任何事情。对该初始化程序的调用将失败的唯一情况是因为前面的alloc调用失败(因此您正在调用一个方法nil,它总是返回nil). If alloc返回零,你已经在恐怖海峡 http://thelaundryfiles.wikia.com/wiki/Case_Nightmare_Green对于这个世界来说,你的流程并不长——这并不是设计 API 的失败案例。

(可空性注释通常用于描述 API 的预期用途,而不是更极端的边缘和角落情况。如果 API 调用仅由于以下原因而失败普遍错误 https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst将其注释为可为空是没有意义的;同样,如果 API 仅在可通过非空参数注释排除的输入上失败,则返回值可假定为非空。)

所以,长话短说:是的,只是把NS_ASSUME_NONNULL围绕你的标题,并运送你的sharedInstance按原样实施。

返回一个nonnull可为空的

这里的情况并非如此,但假设您有一个注释为的值nullable,但你知道(或“知道”)它永远不会为零并且想从你的nonnull- 带注释的方法。并且您处于这样的情况:尝试时会收到编译器警告。

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

return (NSWhatever *_Nonnull)whatever;

在你的情况下,这不需要 - 因为你正在处理id and instancetype特殊类型编译器对可空性转换更加宽容,并且可能不会一开始就发出警告。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我们可以确保 `+ (nonnull instancetype)sharedInstance;` 的可空性吗? 的相关文章

  • 更改 UINavigationBar 中 UIBarButtonItem 的位置

    如何更改 UIBarButtonItem 在 UINavigationBar 中的位置 我希望我的按钮比正常位置高约 5 像素 此代码为 UINavigationBar 创建一个具有图像背景和自定义位置的后退按钮 诀窍是创建一个中间视图并修
  • iphone navigationController :在退出当前视图之前等待 uialertview 响应

    我有一个带有由导航控制器管理的后退按钮的视图 我想在用户单击后退按钮时检查文件是否已保存 如果文件已保存 您将返回到上一个视图 否则 uialertview 会询问您是否要保存文件 所以我这样做了 但视图消失了 然后警报视图出现了 void
  • UIKIT_EXTERN_CLASS 和 UIKIT_EXTERN,这两个常量是什么?

    当我在文档中定义类时 我总是在 interface 之前看到这两件事 UIKIT EXTERN CLASS 和 UIKIT EXTERN 这些常量代表什么以及为什么 Apple 将其放在类之前 另一件事是 有文件 UIKitDefines
  • 在 UITableView 中创建隐藏的 UISegmentedControl

    与 iBooks 应用程序一样 当您下拉表格视图时 会出现搜索栏和分段控件 以允许您在两种类型的视图之间搜索和切换 当您向下拉得足够远时 它会停留在该位置 或者当您将桌面视图拉得足够远时 它会被隐藏 我正在尝试用一个来实现同样的事情UISe
  • stringFromDate 始终为 NIL

    我知道这是一个重复的问题 但是在 stackoverflow 和 google 上搜索了许多类似的问题后 没有一个解决方案对我有用 我正在尝试将从数据库收到的日期转换为字符串格式以在 iPhone 应用程序中显示 我正在按以下方式将日期转换
  • 错误:“消息回复时间太长”向设备手表套件 OS 2 发送消息

    从 Apple Watch 向设备发送消息时出现以下错误 错误域 WCErrorDomain代码 7012 消息回复时间太长 UserInfo NSLocalizedDescription 消息回复时间太长 NSLocalizedFailu
  • iOS 8 UITableView 分隔符插入 0 不起作用

    我有一个应用程序 其中UITableView的分隔符插入设置为自定义值 右0 Left 0 这完美地适用于iOS 7 x 但是在iOS 8 0我看到分隔符插入设置为默认值15在右侧 即使在 xib 文件中它设置为0 它仍然显示不正确 我该如
  • UIWebView stringByEvaluatingJavaScriptFromString 在后台

    在 iOS 应用程序中 我正在运行一个相当大的脚本UIWebView using stringByEvaluatingJavaScriptFromString 就 JavaScript 字符串的长度而言较大 调用 JavaScript 后会
  • iOS 中的视频可以进行反卷积吗?

    我想拍摄击球手挥动棒球的镜头 但球棒很模糊 视频为 30 fps 通过研究 我发现反卷积似乎是最小化运动模糊的方法 但我不知道是否或如何在我的 iOS 应用程序后处理中实现它 我希望有人能给我指出正确的方向 比如如何在 iOS 中应用反卷积
  • 在 Objective-C 中比较两次的最好/最简单的方法是什么?

    我有一个时间的字符串表示形式 例如 11 13 AM 这是使用 NSDateFormatter 和 stringFromDate 方法生成的 我想将此时间与当前时间进行比较 但是当我使用 dateFromString 方法将字符串转回日期时
  • 将数组从控制器传递到视图

    I have UIView UI视图控制器 在 UIViewController 中 我需要能够将项目插入到 6 个整数的固定数组中 然后 我需要将此数组传递给视图 以便它分析该数组并适当地更新屏幕 我该怎么做呢 我尝试过使用标准 C 数组
  • 如何在 Xcode 上共同设计并启用第 3 方 CLI 的强化运行时?

    我的项目需要 Ghostscript 来完成很多任务 因此我已将 gs CLI 工具添加到我的项目资源中 然而 当我尝试对项目应用程序进行公证时 Xcode 向我显示了以下内容 我认为这可能是因为 Ghostscript 便携式 CLI 是
  • 如何在iOS应用程序中实现信号量?

    是否可以在ios应用程序中实现计数信号量 对的 这是可能的 有很多可用的同步工具 同步 NSLock NS条件 NS条件锁 GCD 信号量 并行线程锁 我建议阅读 线程编程指南 http developer apple com librar
  • 在实现文件中声明接口(Objective-C)

    在上一个版本的 xCode 4 3 中 我看到了预定义模板 例如我们的 Master Detail 模板 其中接口声明是在 m 文件中进行的 例如 在文件 MyFile h 中有 interface MyFile property nona
  • 为什么 Objective-C 使用 YES 和 NO 而不是 1 和 0? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 Objective C 使用 YES 和 NO 而不是 1 和 0 是否有任何技术原因 或者只是为了使其更具可读性 使其更具可读性is技术原因
  • Xcode 4 Core Data:如何使用在数据模型编辑器中创建的获取属性

    如何在 Xcode 4 中实现获取的属性 Here is an example of two entities a book and a page 我按照此处的指南创建了一个获取的属性 该属性使用变量 FETCH SOURCE 引用来自源实
  • 空 NSDatePicker

    你好 是否可以让 NSDatePicker 代表 nil 对象 类似 或任何其他方式 谢谢 拉杜 简短回答 否 NSDatePicker 只是忽略无效日期和 nil 例如 这不会更新 NSDatePicker 旧值仍然存在 datePick
  • 从 iOS 中的 App Delegate 调用当前视图控制器中的方法

    我有两个视图控制器 BuildingsViewController 和 RoomsViewController 它们都使用应用程序委托中名为上传的函数 上传函数基本上执行一个 HTTP 请求 如果成功或不成功 都会触发 uialertvie
  • 使用 twitterkit 将图像发布到 Twitter

    我正在尝试使用 Twitter 的新 TwitterKit 和自定义 UI 发布图像和推文 他们提供的唯一文档是如何用他们的观点来做这件事 所以我可以弄清楚如何在没有图像的情况下做到这一点 NSMutableDictionary messa
  • 将 scanf 与 NSString 一起使用

    我希望用户输入一个字符串 然后将输入分配给 NSString 现在我的代码如下所示 NSString word scanf s word The scanf http www cplusplus com reference clibrary

随机推荐