swift - Swift:尽管在 for 循环中进行了赋值,但所有类实例的布尔值都保持不变
问题描述
我有以下数组:
var shoes = Array(repeating: ShoeInfo(), count: 80)
其中ShoeInfo
定义如下:
class ShoeInfo {
var expressionOn: Bool?
var volumeControl: Bool?
var channel: Int?
}
我有一个for
循环:
for i in 0..<16 {
if cond {
shoeArray[i].expressionOn = true
} else {
shoeArray[i].expressionOn = false
}
}
本质上,循环中分配的最后一个值成为数组for
中每个类实例的值!shoes
我显然不想要这个。有人知道如何解决这个问题吗?
解决方案
发生了什么
你只做了一个实例。然后,您创建了一个数组,其中包含对该单个实例的 80 个引用。自己看,试试:
for shoe in shoes {
print(ObjectIdentifier(shoe))
}
你会看到所有的引用都指向一个单一的对象。
您可能正在寻找什么
这是:
let shoes = (0..<80).map { _ in ShoeInfo() }
该map
调用将为 range 中的 80 个整数中的每一个调用一次闭包0..<80
,这将导致实例化 80 个不同的鞋对象。
有用的背景
Array(repeating:_count:_)
按值获取其参数(注意没有inout
)。因此,当您调用它时,您作为参数传递给repeating
参数的任何内容都会被复制。
对于类,“复制”需要对完全相同的堆分配对象进行新引用。它通常也保留在过程中(将其引用计数增加一),但这在这里并不重要。因此,当您调用 时Array(repeating: ShoeInfo(), count: 80)
,只创建了一个ShoeInfo
实例,然后代码将其复制了 80 次,这意味着它对同一个实例进行了 80 次复制引用。
对于结构,“复制”意味着完全复制它们,成员明智的。当您尝试 时Array(repeating: ShoeInfoAsAStruct(), count: 80)
,您将创建一个ShoeInfoAsAStruct()
,然后将其复制到阵列的 80 个插槽中的每一个中,从而产生 80 个完整副本。您最终会得到 80 个不同的副本,每个副本都可以单独编辑。这就是为什么切换到struct
工作。
推荐阅读
- json - 无法运行 powershall 脚本
- html - 使用 goquery 将 html 文本和嵌套标签转换为文字字符串
- python - matplotlib.patches.Arc 并使用 clip_path 参数
- masstransit - 为什么在构造函数中注入的 MassTransit ConsumeContext 不包含 Message?
- android - 我正在使用 Android Studio 中的布局
- c# - “连续快速切多个水果给玩家双倍/三倍积分”
- java - 如何在 Z3 java API 中获取上限和下限?
- flutter - 颤振:如何从扩展面板中删除图标
- reactjs - 输入“承诺”
' 缺少类型 'ReactElement 的以下属性 - python - 使用 args 定义函数以在 df.transform 中使用