为什么 NSSet/NSMutableSet/NSCountedSet 不强制不可变对象作为条目?

2023-12-12

NSDictionary 键是 id 但集合的值只是 id,文档表明它们的值被保留。根据设置集合编程主题的基础知识 docs:

但是,您可以修改单个对象本身(如果它们支持修改)。

如果修改对象,这可能会影响该对象的哈希值,从而影响查找。我认为 NSSet 是快速查找?

下面的示例展示了如果您改变对象,事情会如何崩溃:

    NSMutableString *str = [NSMutableString stringWithString: @"AWESOME"];
    NSCountedSet *countedSet = [[NSCountedSet alloc] init];
    [countedSet addObject: str];
    [countedSet addObject: str];

    NSLog(@"%@", @([countedSet countForObject: @"AWESOME"]));

    [str appendString: @" NOT AWESOME"];
    NSLog(@"%@", @([countedSet countForObject: @"AWESOME NOT AWESOME"]));
    NSLog(@"%@", @([countedSet countForObject: @"AWESOME"]));
    NSLog(@"%@", @([countedSet countForObject: str]));

    for(NSString *s in countedSet) {
        NSLog(@"%@ - %@", str, @([countedSet countForObject: s]));
    }

    NSSet *set = [NSSet setWithArray: @[ str ]];
    NSLog(@"Set Contains string, %@", @([set containsObject: str]));
    [str appendString: @"asdf"];
    NSLog(@"Set Contains string, %@", @([set containsObject: str]));
    NSLog(@"%@", set);

并用我的解释输出:

[64844:303] 2          // Count is 2
[64844:303] 0          // Count should be 2 - if it looks for the literal string
[64844:303] 0          // Count should be 0, but can't find original object either
[64844:303] 0          // Count should be 2 - asking for actual object that's in there
[64844:303] AWESOME NOT AWESOME - 0   // Should be 2 - asking for actual object that it just retrieved
[64844:303] Set Contains string, 1    // Correct, pre-mutation
[64844:303] Set Contains string, 0    // Should be true, object is in there
[65070:303] {(
    "AWESOME NOT AWESOMEasdf"   // see?  It's in there
)}

My take:

该集合可能基于哈希值的存储桶,当该集合后面的哈希被更改时,它不知道该怎么做并且查找被破坏。该领域缺乏文档。

我的问题重申: 文档说你可以改变对象,这并不直观。 变异对象会破坏集合。 搞什么?


文档中的那句话令人困惑。然而,请注意下面的三段接着说:

如果可变对象存储在集合中,则hash的方法 对象不应该依赖于可变对象的内部状态 或者可变对象在集合中时不应被修改。 例如,可以将可变字典放入集合中,但必须 当它在那里时不要改变它。 (请注意,可能很难 知道给定对象是否在集合中)。

您的代码演示的是基于哈希的集合类的已知属性。如果实现一个关键对象使得复制返回原始对象(本质上是可变的),它也会影响字典。

没有真正的方法来测试对象是否可变。因此,它不能强制不变性。

另外,正如上面引用中提到的,可以创建一个可变类,其hash并且平等不受突变的影响。

最后,如果这些集合类只能与可复制类一起使用并复制元素(就像字典复制其键),那么它们的实用性就会受到严重限制。集合用于表示关系等,如果您尝试在对象之间建立关系,而是与单独的副本建立关系,则不会这样做。

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

为什么 NSSet/NSMutableSet/NSCountedSet 不强制不可变对象作为条目? 的相关文章

随机推荐

  • Twisted Python:无法写入正在运行的生成进程

    我的问题是 在生成进程后 子进程正在循环以从其标准输入获取数据 我想使用 Echo Process pipes 0 write data 或 Echo Process writeToChild 0 data 向其写入新数据 但两者都不起作用
  • 无法使用 virtualenv 运行 Apache2

    我正在制作一个基于 Django 的网站 在服务器上安装了 Python 3 5 但我的项目需要 Python 3 6 我决定使用 virtualenv 我成功安装了所需版本的 Python 但无法使其与 Apatche2 一起使用virt
  • ruby 1.9 和rails 的soap 客户端

    到目前为止 我使用soap4r 作为 Ruby 1 8 x 的 SOAP 客户端 但现在我正在转向 Ruby 1 9 x 不幸的是 soap4r 不能与 Ruby 1 9 x 一起工作 我只是得到了 无效的多字节转义 这似乎无法解决 主要是
  • 如何连接派生表?

    sql语句是这样的 select posts id posts title from posts inner join select distinct post id created at from comments order by cr
  • 是否可以即时更改 PrimeFaces 主题?

    我有一个多租户系统 用户签名后将在应用程序中拥有自定义主题 我想知道是否可以在用户签名后 动态 更改主题 我是 Primefaces 的新手 感谢您的帮助 Primefaces 已经实现了 jQuery UI主题滚轮 在你的 web xml
  • 从分叉创建新的拉取请求,而无需提交前一个分叉

    因此 我对其他人的存储库进行了一些提交 然后提交了相同的拉取请求 我的旧拉取请求尚未合并 现在我需要提交一个新的拉取请求 而不需要以前的提交 但要对我的分叉进行新的更改 我需要我的旧拉取请求及其提交也留下来 我怎样才能做到这一点 要真正理解
  • Nginx 自动将 HTTP 重定向到 HTTPS

    我正在尝试重定向我的所有流量http to https自动地 如何对我的所有域和子域进行 301 重定向 这是 NGINX 配置文件 upstream app server server unix run DigitalOceanOneCl
  • 为什么 SQL Server 将 SS 视为 Umlaut-S (ß)?

    当我运行以下查询时 select charindex COMMISSIONING 它返回 6 我专门选择 作为函数 因为我认为它不太可能出现在我的任何数据中 这几周工作得很好 但现在突然它在没有 的地方检测到 因此搞砸了我的功能 有人可以告
  • 重命名列后出现 keyerror

    I have df df pd DataFrame a 7 8 9 b 1 3 5 c 5 3 6 print df a b c 0 7 1 5 1 8 3 3 2 9 5 6 然后将第一个值重命名为this df columns valu
  • “git push appengine master”中需要用户名和密码

    这是我第一次使用 Google App Engine 我正在尝试上传 PHP 网站 我正在尝试使用 git 上传它 我遵循了他们的教程 最后他们说要输入这段代码 所以我就这么做了 我尝试在 git bash 中输入这段代码 这是代码 git
  • MVC 的 PHP 简单数据库连接类

    我已经为简单的 MVC 模式构建了新的数据库连接类 我需要知道这是执行此操作的正确方法
  • 存储过程中返回的地理列未显示在实体框架自动生成的复杂类型中

    我正在使用 Entity Framework 6 和 Net 4 5 我有一个选择并返回数据的存储过程 返回列之一是地理类型 在 Visual Studio 2013 中 我右键单击 edmx 文件 单击 从数据库更新模型 此操作获取我的存
  • 正则表达式在匹配字符串时如何忽略转义引号?

    我正在尝试编写一个正则表达式 它将匹配除尚未转义的撇号之外的所有内容 考虑以下 我的目标是编写一个基本上匹配其字符串部分的正则表达式 我正在考虑诸如此类的事情 为了匹配一个简单的字符串 但我一直在试图弄清楚如何在该撇号上进行负向后查找 以确
  • $wpdb->insert() 给出错误未定义函数

    我在 wp content theme mytheme 文件夹中创建了一个新文件 在文件中我编写了简单的查询 global wpdb insert wpdb gt insert wp test array orderID gt GET or
  • Linkify 函数中的自定义链接

    我正在尝试使用此 html 创建基于不同按钮的自定义链接
  • 如何使用材质设计卡制作阴影?

    这是我想要的结果 制作一张定制卡 custom cards Widget card String image return Container child Image asset image fit BoxFit cover decorat
  • 用于主轴标签的 Excel 宏

    我正在尝试编写一个宏来格式化图表以实现统一 我陷入了我认为最简单的部分 标记轴 它不会标记主值轴 y 轴 我在2010年和2013年多次录制过这个宏 有什么问题吗 我运行该宏 它在第 3 行进行调试 几乎就像标签不存在一样 仅运行前两行就证
  • 查找近似字符串匹配并替换为预定义字符串的有效方法

    我需要建立一个NER系统 命名实体识别 为简单起见 我通过使用近似字符串匹配来完成此操作 因为输入可能包含拼写错误和其他细微修改 我遇到过一些很棒的图书馆 例如 模糊模糊甚至更快快速模糊测试 但不幸的是我没有找到一种方法来返回匹配发生的位置
  • 使用 php 读取 csv 文件的最简单方法,然后选择一个特定值

    预先感谢您的时间 帮助 我是一个学习 php 的新手 所以请记住这一点 第一个问题 我需要一个读取 csv 文件的 php 脚本 第二个问题 如何回显该文件中的特定单元格 行和行 列 我在类似的回复中找到了这个脚本 该脚本完美地读取了整个文
  • 为什么 NSSet/NSMutableSet/NSCountedSet 不强制不可变对象作为条目?

    NSDictionary 键是 id 但集合的值只是 id 文档表明它们的值被保留 根据设置集合编程主题的基础知识 docs 但是 您可以修改单个对象本身 如果它们支持修改 如果修改对象 这可能会影响该对象的哈希值 从而影响查找 我认为 N