Swift 相等需要 ObjectIdentifier 吗?

2023-11-30

我们有一个自定义 Swift 类的多个实例,它继承自 SKSpriteNode,并且能够正确执行以下代码(针对此问题进行了大幅简化):

let instance1 = CustomClass()
let instance2 = CustomClass()
let instance3 = CustomClass()
let instance4 = CustomClass()

let array1 = [instance1, instance2]
let array2 = [instance3, instance4]

func check(testInstance: CustomClass) -> Bool {
   return array1.filter({ $0 == testInstance }).count > 0
}

check(testInstance: instance3)

换句话说,执行check(testInstance: instance3)false正如预期的那样。

然而,我们做了很多改变,并且check停止工作。

CustomClass不执行Equatable协议。我们只想检测独特的实例。

当我们使用时它才开始工作ObjectIdentifier,这意味着函数更改为:

func check(testInstance: CustomClass) -> Bool {
   return array1.filter({ ObjectIdentifier($0) == ObjectIdentifier(testInstance) }).count > 0
}

Why is ObjectIdentifier需要什么,什么时候应该使用它来实现对象相等?

这是用 Swift 3 编写的。


Why is ObjectIdentifier需要什么,什么时候应该使用它来实现对象相等?

你不需要使用ObjectIdentifier为了在这种情况下执行恒等比较,您可以简单地使用恒等运算符===相反,作为马丁在这里说,对于类实例相当于使用ObjectIdentifier's ==超载:

func check(testInstance: CustomClass) -> Bool {
    return array1.contains(where: { $0 === testInstance })
}

另请注意我们正在使用contains(where:) over filter{...}.count > 0,因为前者在找到匹配元素时会短路,而后者会评估整个序列(并创建不必要的中间数组)。

直接使用==执行对象的身份比较may已经起作用,因为CustomClass最终继承自NSObject,符合Equatable通过定义an ==超载那个叫isEqual(_:),默认情况下执行身份比较。

但一般来说,这应该not可以依赖——实施isEqual(_:)可以重写以根据属性值而不是身份来执行比较。此外,从语义上Equatable要求实施==基于正在比较的实例的所有可见方面(即属性值)。

From 文档:

平等意味着可替代性——任何两个比较的实例 同样可以在任何依赖于它们的代码中互换使用 价值观。为了保持可替代性,==操作员应考虑 考虑一个事物的所有可见方面Equatable type.

因此使用==因为对你的班级进行身份比较从来都是不正确的,尽管它最初可能有效。

至于什么时候ObjectIdentifier应该使用,实际上你永远不需要它just进行身份比较。对于类,您应该使用===运算符,对于元类型,您应该简单地使用==专门为它们定义的重载(在这种情况下,身份恰好等于相等,因为每个新元类型实例都是唯一的)。

主要用途ObjectIdentifier确实是它的hashValue实现,它派生自初始化对象的指针值。这可能很有用,例如,允许元类型Dictionary键(比较制作一个 Swift 字典,其中键是“Type”?).

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

Swift 相等需要 ObjectIdentifier 吗? 的相关文章

  • 使用 nib 作为带有 nib 类的表节标题

    我想创建一个加载 nib 文件并将其设置为标题 UIView 的节标题 这个 nib 文件还将有一个关联的类 其中插座和操作连接到 因此我想像平常一样使用 nib 加载该类 我在网上搜索并找到了几个类似的答案 但我找不到任何适合我的答案 经
  • 来自索引范围 Swift 的新数组

    我怎样才能做这样的事情 从数组中取出前 n 个元素 newNumbers numbers 0 n 目前出现以下错误 error could not find an overload for subscript that accepts th
  • 进入后台时 Alamofire 请求卡住?

    我正在使用 Alamofire 调用 Web 服务 该服务需要相当长的时间才能加载 如果应用程序进入后台 当我返回应用程序时 我会被加载程序卡住 我想这是因为调用永远不会向我的完成处理程序返回任何内容 我该如何解决这个问题 您可以使用后台抓
  • 使用 UItableViewCell 类型的表达式初始化“CustomCellView *”的指针类型不兼容

    你能帮我理解和 修复下面的错误吗 我不明白CustomCellView是一个子类UItableViewCell 代码已编译 但警告仍然存在 Incompatible pointer type initializing CustomCellV
  • 如何在 iOS 中将 Firebase 对象持久保存到磁盘?

    看起来Firebase http www firebase comiOS 实现不支持客户端模型的离线缓存 这在实践中意味着 对于需要身份验证的 Firebase 应用程序 您需要首先进行身份验证并等待 Firebase 完成登录 检查用户身
  • 如何在 Swift 中使用 CoreBluetooth 更新 BLE 设备的电池电量?

    func peripheral peripheral CBPeripheral didDiscoverCharacteristicsFor service CBService error Error for c in service cha
  • 是否可以更改枚举中的关联值?

    我正在使用 Swift 枚举 想知道是否有一种方法可以更改枚举的关联值 例如下面的代码尝试但失败了 enum myEnum case SomeCase Int mutating func someFunc switch self case
  • 与新 Apple Music 应用程序中相同的动态状态栏

    是否可以动态着色statusBar这是在新的苹果音乐应用程序 Edit iOS 8 4 中的新 Apple Music 应用程序具有此功能 打开应用程序 选择并播放歌曲 状态栏为白色 向下滑动播放器控制器以查看 我的音乐 控制器 它有黑色状
  • 在 ios 版 Ionic 中接收 URL

    我正在使用离子框架 我正在尝试设置一种从另一个应用程序接收网址的方法 就像 您在浏览器中 单击共享 然后将链接发送到另一个应用程序 我的应用程序 我找到了这个cordova https stackoverflow com questions
  • 二元运算符“/”不能应用于两个(Int)操作数[重复]

    这个问题在这里已经有答案了 我得到了Binary operator cannot be applied to two Int operands当我将以下代码放入 Xcode 中的 Swift Playground 时出错 func sumO
  • 是否可以使用UIPageControl来控制UITableView的移动?

    从Apple示例 PageControl 中我们可以知道UIPageControl可以用来控制scrollview中页面的移动 由于 UITableView 是 UIScrollView 的子类 我想使用 UIPageControl 来控制
  • 在 JavaScript 中检测页面是否加载到 WKWebView 中

    如何使用 javascript 可靠地检测到页面已加载到 WKWebView 中 我希望能够检测到这些场景 iOS 和 WKWebView iOS 和 Safari not iOS 关于 UIWebView 有一个类似的问题here htt
  • NSURLCache 不缓存

    我正在使用 Xcode 6 1 6A1030 iOS7 和 iOS8 模拟器 NSURLCache 似乎没有缓存任何东西 我使用 Cache Control 标头 我的服务器返回带有 max age 6000 的 Cache Control
  • TTTAttributedLabel 可点击截断标记

    我有一个 TTTAttributedLabel 并为其指定了一个自定义属性截断标记 NSAttributedString atributedTruncationToken NSAttributedString alloc initWithS
  • Swift:协议、结构、类

    我开始学习 Swift 语言 但在理解协议 结构和类方面遇到了困难 我来自 Android 方面的编程 所以我相信 Swift 协议基本上是 Java 接口 其中每一个的正确用例是什么 这些类比并不 完全 正确 但这就是我所理解的要点 是的
  • 循环多个 UIAlertController

    在某些情况下 我的应用程序需要显示多个警报消息 错误消息在启动时收集 并且需要一次向用户显示一条 当第一个被确认后 应该呈现下一个 问题在于 显然 它们都试图同时执行 有没有一种聪明的方法可以同步执行此操作 这是一些简单描述我想要做的事情的
  • 如何在Sprite Kit中实现鼠标关节?

    我已经在 iOS 上用 Cocos2d Box2d 编写了拖放功能的工作实现 我需要将它移植到 Sprite Kit 逻辑非常基本 当用户触摸屏幕时 找到手指下的精灵 在找到的精灵和场景的物理体之间创建鼠标关节 将关节的目标设置为触摸位置
  • cordova插件条码扫描仪打不开扫描

    我的条形码扫描仪插件有问题 我不是天才 我不太了解如何编写网络应用程序 我使用phonegap和cordova 并且尝试制作一个网络应用程序 在单击链接后扫描条形码 我之前已经使用此命令行安装了该插件 cordova plugin add
  • 检查 Swift 中关联类型是否符合协议

    在类似情况下 如何检查对象是否符合 可表示 协议 protocol Representable associatedtype RepresentType var representType RepresentType get set cla
  • 如何将自定义 C 代码放入 SwiftPM 包中?

    我正在尝试将 C 代码打包到 Swift 模块中 我们称之为CModule 一旦我将其放入项目的基本文件夹中 Swift模块 并配置了搜索路径 我可以在 Swift 文件中自动完成工作 并检测错误 警告 问题是 导入时它无法识别该模块 并且

随机推荐

  • 如何在CSS中获取背景图像上的扫描线

    我有一个整页背景图像 我想在其上覆盖扫描线 我想复制我在二十世纪九十年代的数字艺术中看到的更传统的对角线扫描线效果 例如实现here在 Bootstrap 的模式掩码 5 中 我看过一些关于对角线扫描线的教程 但一直找不到这样的东西 我将如
  • 注册自定义控件失败

    我尝试在 webconfig 文件中注册我的用户控件 因为我收到 元素不存在 错误 但当我尝试在 webconfig 中注册它们时 我收到以下错误 Invalid or missing attributes found in the tag
  • 如何在displaytag中导出带有xlsx扩展名的excel文件

    We used 显示标签用于导出文件xls格式 但我想要它xlsx格式 有什么办法可以将excel文件转换为新格式吗 我将显示标签中的扩展名更改为xls 到 xlsx
  • 使用 jQuery 和 PHP 实现长轮询

    我想构建一个基于 JavaScript jQuery 将用于 AJAX 和 PHP 的聊天 我听说这样做的一个好方法是使用长轮询 我确实理解这个想法 但我不知道如何在服务器端实现它 无限循环听起来是个坏主意 您不想创建无限循环 但可以设置超
  • 可滚动 div 无法在 Android 模拟器、iPhone 模拟器中工作

    我正在使用phonegap 我想保留固定的页眉和页脚 并且我想在它们之间滚动内容 为此 我将 div 与 div width 249px height 299px background color Gray overflow y auto
  • 如何使用宏在 SAS 中获取当前月份名称和年份

    我正在 SAS 中触发一封邮件 该邮件应在邮件中保存当前月份和年份 如何创建宏变量 month year这样 month应显示十月 year应显示 2020 目前使用 let sysmonth sysfunc month sysdate d
  • SqlDataSourceEnumerator.Instance.GetDataSources() 找不到本地 SQL Server 2008 实例

    我使用以下代码列出所有远程和本地 SQL Server 实例 public static void LocateSqlInstances using DataTable sqlSources SqlDataSourceEnumerator
  • 如何使用新的 OpenSSL 库编译 PHP

    我正在尝试使用 OpenSSL 编译 PHP 只需配置即可与默认 OpenSSL 库 0 9 6 配合使用 with openssl usr 但是 我安装了一个新的 OpenSSL 库 1 0 0 我想用它来编译 PHP 这个图书馆位于 u
  • 如何仅通过这种回溯找到第一个解决方案

    我正在尝试编写一个数独求解器 它将仅返回第一个可能的解决方案 我设法用 void 方法打印所有可能的解决方案 但我不能在第一个发现时停止 我知道首选方法是切换到布尔方法并返回true上树 但我找不到正确的写法 我尝试的任何方式总是给出编译错
  • setTimeout 函数的第三个参数是什么?

    我正在阅读一些使用 Promise 对象的代码 有一个setTimeout函数有三个参数 我想知道第三个参数是做什么的 因为通常它只有两个参数 代码如下 function timeout ms return new Promise reso
  • 在意图android中传递一个数组

    所以我一直假设你不能在带有额外功能的活动之间传递数组 但我刚刚浏览 Bundle 类文档并看到putStringArray String key String value and public String getStringArray S
  • 使用自己的登录表单进行太多重定向 - Spring Security

    我想制作自己的登录表单 当我更改登录页面时 我无法打开它 Google Chrome 告诉我此页面的重定向太多 My code RequestMapping value login method RequestMethod GET publ
  • 通过从“外部”Angular JS 更改服务,观察者停止工作

    我正在这样做 angular element body injector get myService somevar true 我在其他地方抓住了它 scope watch function return myService somevar
  • 扫描仪应该只实例化一次吗?如果是这样的话为什么会这样呢?

    我知道我在这里有点冒险 但我似乎无法理解为什么我们不能两次创建 Scanner 类的实例 我将添加一个示例以防万一 import java util Scanner public class Nope public static void
  • 使用 jsFiddle 的全局变量

    在 jsFiddle 环境中 我希望创建一个循环 以随机顺序显示数字 1 到 10 不重复 jsFiddle 在这里 除此之外 在 jsFiddle 环境中使用全局变量有困难 将不胜感激 jsFiddle 中全局变量的解释 让我的代码工作
  • AngularJS + 路由 + 解析

    我收到此错误 错误 错误 injector unpr http errors angularjs org 1 3 7 injector unpr p0 HttpResponseProvider 20 3C 20HttpResponse 20
  • 如何使用 Ant 重命名文件和文件夹

    如何使用 Ant 重命名多个文件和文件夹 对于我知道的文件我可以这样做 question 如何对文件夹做同样的事情 例如 文件夹集 输入 com google appengine eclipse sdkbundle 1 5 2 r37v20
  • 反转 DOMNodeList 中项目的顺序

    你好 我正在制作 RSS 阅读器并且正在使用 DOM 现在我卡住了 试图反转 DOMNodeList 中项目的顺序 我可以用 2 个周期来完成 一个周期将其作为数组 另一个周期用于rsort 有没有办法反转 DOMNodeList 中的顺序
  • 如何使用phonegap-videoplayer-plugin 播放Youtube 视频?

    我在用用于播放视频的 Phonegap 插件在我的 iOS 应用程序中 我可以播放 URL 格式的视频 例如http easyhtml5video com images happyfit2 mp4 如何使用phonegap videopla
  • Swift 相等需要 ObjectIdentifier 吗?

    我们有一个自定义 Swift 类的多个实例 它继承自 SKSpriteNode 并且能够正确执行以下代码 针对此问题进行了大幅简化 let instance1 CustomClass let instance2 CustomClass le