2015-03-25 43 views
13

在Objc字符串中,数组和字典都是引用类型,而在Swift中它们都是值类型。为什么Swift中的字符串,数组和字典更改为值类型

  1. 我想弄清楚什么是幕后的原因,我的理解,无论是引用类型或值类型,对象住在两个Objc和斯威夫特堆。

  2. 编码变得简单了吗?即如果它是引用类型,那么指向该对象的指针可能不是零,因此需要检查指针和该对象不为零以访问该对象。而如果它是值类型,那么只需要检查对象本身?

  3. 但就内存分配而言,值类型和引用类型是相同的,对吧?两个都分配了相同大小的内存?

感谢

回答

15

Objective-C中的数组,字典等常常是可变的。这意味着当我将一个数组传递给另一个方法时,然后该数组在另一个方法的后面被修改,令人惊讶的是(轻轻地说)会发生行为。

通过制作数组,字典等值类型,可以避免这种令人惊讶的行为。当你收到一个Swift数组时,你知道没有人会在你的背后修改它。可以在背后修改的对象是问题的主要来源。

实际上,Swift编译器会尽可能地避免不必要的复制。所以即使它说一个数组被正式复制,也并不意味着真的被复制。

+2

我从来没有陷入这个问题的主要来源。但是,数组的副本有多深?当数组发生变化时,为什么它是“问题的主要来源”,但当数组中的某个项目改变了其中一个属性时,却没有“主要的问题来源”?他们为什么认为斯威夫特团队认为项目的改变不是“问题的主要来源”,而改变阵列长度是长期以来的“主要问题来源”,为什么他们改变了他们的观点? – 2015-03-25 11:43:05

+0

我主要同意你的看法,但我想,在Obj-C中,只要没有其他选择,开发人员不必传递/请求可变对象。不可修改的对象不能在调用者后面修改,所以从这个角度来看,你的逻辑看起来有点破碎。 – holex 2015-03-25 12:18:37

+0

我的逻辑观点很简单,就是“在我背后修改”在实践中不会造成严重问题。这是斯威夫特的“我们解决一个只存在于理论上的问题”特征之一。生产代码中只有一次是否存在这个问题?所以一开始就有一个快速和肮脏(不一致)的解决方案来解决这个问题,现在我们有一个一致的解决方案来解决一个没有问题的解决方案,这个解决方案有时会让问题变得更加困难并且会有性能问题。 – 2015-03-25 13:05:13

-4

我不知道,这是否是其背后的真实想法,但有它历史的观点:

在开始的时候,一个数组复制引用,当表现你改变了一个项目。当你改变数组的长度时,它的行为是按值进行的。他们出于性能考虑(较少阵列拷贝)。但是,当然这是,呃,我怎么能用Swift在政治上表达这个问题呢,呃,我们称之为“如果你能赢得一些表现,你可能永远不需要”,那么就不要关心一个好的结构。 。有些人称这种写入时复制功能不太聪明,因为COW是透明的,而这种行为并不透明。典型的斯威夫特措辞:使用流行语,用它的方式,它适合斯威夫特,不关心正确性。

后来在数组上得到了一个完整的复制行为,更不容易混淆。 (你记得,Swift的可读性很明显,在Swift的概念中,可读性意味着“阅读的字符少”,但并不意味着“可以理解”)典型的Swift措辞:使用流行语,用它来适应Swift,不关心正确性,我已经提到过了吗?)

所以,我想这仍然是性能加上可以理解的行为,可能会导致性能下降。 (你会更好地知道在你的代码中需要一个副本,并且你仍然可以这样做,并且如果源数组是不可变的,你可以从Cocoa得到一个0操作。)当然,他们可以说:“好的,按值一个错误,我们改变了这一点。“但他们永远不会说。

但是,现在在Swift中的数组的行为一致。斯威夫特取得重大进展!也许你可以在晴朗的一天把它称为编程语言。

+4

这并不回答任何问题。这只是你对Swift的一般看法。 – HAS 2015-03-26 06:30:59

+0

@HAS这是错的。 – 2015-03-26 08:34:48

6

Swift团队在官方开发者论坛上非常活跃。所以,我假设既然你没有问那里,你就会更加好奇社区对变革意味着什么的更广泛的“意义”,而不是技术实现的细节。如果你想正确理解“为什么”,那就去问问他们:)

对我最有意义的解释是对象应该负责响应和更新你的应用程序的状态。值应该是您的应用程序的状态。换句话说,数组或字符串或字典(以及其他值类型)决不应负责响应用户输入或网络输入或错误条件等。对象处理该数据并将结果数据存储到这些值中。

Swift中的一个很酷的特性是,值类型可以封装规则和逻辑,因为它们可以封装规则和逻辑,这使得一个复杂的值类型(像一个字典或类似Person的自定义类型,而不是一个简单的Float)更加可行有功能。如果我将一个值类型Person作为结构写入,那么Person结构可以有一个函数,用于由于结婚等更新名称。这只与数据有关,而不涉及/管理/状态。对象仍然会决定何时更新Person的名称,但是如何安全地/可测试地执行此操作的业务逻辑可以包含在Value Type中。因此,为您提供增加隔离度和降低复杂性的好方法。

2

除了前面的答案,还有多线程问题需要考虑共享基于引用的集合类型,我们不必担心共享基于值的类型实例并具有写入时复制行为。多核心即使在iOS设备上也越来越多,所以对于Swift语言开发人员来说,它已成为更多问题。

相关问题