让我们用这两个简单的类来表明我的问题:
class Object{
var name:String?
// keep it simple... and useless
}
class TestClass {
var objects:AnyObject[]?
func initializeObjects (){
objects?.insert(Object(), atIndex:0) // Error
objects?.insert(Object(), atIndex:1) // Error
objects?.insert(Object(), atIndex:2) // Error
}
}
通过这个实现,我得到3个错误Could not find member 'insert'
,我尝试将对象添加到objects
数组中。
现在,如果我从objects
定义和initializeObjects
中的可选链中删除可选项,那么它可以正常工作(这里是工作代码)
class Object{
var name:String?
}
class TestClass {
var objects:AnyObject[] = AnyObject[]() // REMOVE optional and initialize an empty array
func initializeObjects (){
objects.insert(Object(), atIndex:0) // Remove Opt chaining
objects.insert(Object(), atIndex:1) // Remove Opt chaining
objects.insert(Object(), atIndex:2) // Remove Opt chaining
}
}
我无法理解第一次实施中的错误。
如果objects?
不是objects
,我认为它会与nil
进行核对,此时它会使用insert:atIndex:
添加一个元素。但我可能错了 - .-
答案 0 :(得分:5)
Swift中的数组是结构,结构是值类型
Swift中的Optionals实际上是枚举(Optional<T>
或ImplicitlyUnwrappedOptional<T>
)。
当您展开值类型的可选(隐式或显式)时,您获得的实际上是结构的常量副本。而且你不能在常量结构上调用mutating
方法。
执行objects?.insert(Object(), atIndex:0)
基本上意味着:
if let tmp = objects {
tmp.insert(Object(), atIndex:0)
}
作为一种变通方法,您需要将展开的值分配给变量,然后将变量分配回可选属性。这就是价值类型的运作方式。
这对于任何结构都是可重现的,不仅仅是数组:
struct S {
var value: Int = 0
}
var varS: S = S()
varS.value = 10 //can be called
let constS: S = S()
constS.value = 10 //cannot be called - constant!
var optionalS: S? = S()
optionalS?.value = 10 //cannot be called, unwrapping makes a constant copy!
//workaround
if optionalS {
var tmpS = optionalS!
tmpS.value = 10
optionalS = tmpS
}
此处进行了一些相关讨论:https://devforums.apple.com/thread/233111?tstart=60