为什么有人会在Objective-C中使用数据结构的非NSMutable等价物?当你需要一个不应修改的const
对象时?使用非NSMutable类以任何方式改善性能吗?还有其他任何情况吗?
答案 0 :(得分:3)
我头脑中的两个主要原因:
你也倾向于认为有利于原始价值的固有保存的论据是有用的,特别是在语义和设计模式方面。
不可变类在一个例外中往往不会更有效 - 例如,如果你采用可变数组的不可变副本,那么就可以确切地知道需要多少存储空间,而且确切地说可以存储多少存储空间。被分配。由于内存分配需要时间,因此可变集合往往会保留一些备用存储,因为它们无法预测它们将如何增长。
答案 1 :(得分:2)
const
与非可变对象没有直接关系;我对后者比较熟悉,所以这就是我要谈的内容。
不可变对象就像预订一样。想象一下,您在一家只能预订的繁忙餐厅工作 - 所有客人都必须预订。当有人在六点钟打电话预约八个人的时候,你知道你会期待六个人在六点。当然,这可以让事情变得可预测。你知道要设置一个可以容纳8个人的桌子(使用多个桌子是没有意义的,特别是在繁忙的餐厅)。你通知厨房并告诉他们在六点钟之后几分钟就会收到8个订单(好吧,也许你不会,但你可能会这样)。通过这种方式,一切运行顺利,没有延迟。当八人聚会在六点迅速到达时(因为这个世界上的每个人都非常准时),你带领他们到他们的座位上,他们下令,享受他们的饭菜。没有任何问题。
如果预订从未指定人数或时间,则会出现问题。想象一下有人打电话告诉你期待一群人共进晚餐。在这种情况下,您没有任何信息。一个团体可以是一对约会对象,一个四人家庭,或二十几个人的公司职能。他们可能会因为他们在看电影而迟到,因为他们有一个小孩,或者在不同的时间,因为无法协调每个人。在这种情况下,您将不得不争先恐后地为每个人找到座位,厨房可能会突然被大量订单所淹没。或者你可以阻挡许多座位,而厨房可能会发现自己无所事事。在任何一种情况下,如果您高估或低估,都会有延迟和失去潜力。任何事情都可能发生。
在这个比喻中,餐厅将是运行时系统,而预订是对象。在第一个场景中,您有一个不可变对象,如NSArray
。系统知道它将保存多少数据,有多少元素,以及运行时,它们是什么类型。系统知道大小不会改变,因此它可以优化RAM以绕过该阵列,而不会留下任何预防位。一切都很顺利,因为一切都是已知的。
相比之下,NSMutableArray.
一无所知用户可能会添加更多元素,因此系统必须争先恐后地寻找更多RAM,而不是使用相同的时钟周期来处理某些操作;用户可能用较大的元素替换中间的元素,必须偏移所有后面的元素 - 这涉及复制所有后面的元素。在某些情况下,它可能涉及将数组或字符串的所有元素或任何内容复制到新位置,(可能)昂贵的操作。这可能会带来显着的性能开销,尤其是当您使用大量开发时。例如,在Java中,连接字符串涉及将整个现有字符串复制到新的内存位置,并使垃圾收集器处理旧字符串。
另一个令人信服的理由是,您要更改数据有点困难。用户(该类)必须明确地制作一个可变副本,这有助于确保他们知道他们正在做什么。这个优点尤其值得注意多线程 - 您不希望将可变对象传递给在后台线程上运行的东西,因为前台线程(或任何其他)可能正在修改该对象,因为它正被修改原始线程,导致非常有趣的结果。