我创建了以下类:
class Person {
private var name: String = ""
private init(name thisName: String) {
name = thisName
}
class func CreatePerson(#type: String, name: String) -> Person! {
if type == "girl" {
return Female(name: name)
}
else if type == "boy" {
return Male(name: name)
}
return nil
}
func PrintName() {
println(name)
}
}
class Male: Person {
override init(name thisName: String) {
super.init(name: thisName)
}
deinit {
println("Deleting a male.")
}
}
class Female: Person {
deinit {
println("Deleting a female.")
}
}
class AnotherClass {
var secondPeopleArray: [Person]! = nil
func DoSomething(#people: [Person]) {
secondPeopleArray = [Person]()
for person: Person! in people {
let male: Male! = person as? Male
if male != nil {
secondPeopleArray.append(male)
}
}
}
}
如您所见,我创建了一个名为Person的类,其中包含两个子类(男性和女性) . 我还创建了一个类(AnotherClass),它接受一个Person类数组并构建一个新的Male类数组 . 如你所见,
我创建了以下代码来构建Person类数组并调用Another类函数DoSomething . DoSomething分配数组并过滤people数组,并仅将Male类附加到secondPeopleArray成员 .
var firstPeopleArray = [Person]()
var firstPerson: Person = Person.CreatePerson(type: "boy", name: "Bill")
var secondPerson: Person = Person.CreatePerson(type: "boy", name: "Ted")
var thirdPerson: Person = Person.CreatePerson(type: "girl", name: "Nancy")
var fourthPerson: Person = Person.CreatePerson(type: "girl", name: "Diane")
firstPeopleArray.append(firstPerson)
firstPeopleArray.append(secondPerson)
firstPeopleArray.append(thirdPerson)
firstPeopleArray.append(fourthPerson)
var anotherClass: AnotherClass = AnotherClass()
anotherClass.DoSomething(people: firstPeopleArray)
anotherClass.DoSomething(people: firstPeopleArray)
for person in firstPeopleArray {
person.PrintName()
}
如您所见,DoSomething函数被调用两次 . 这是故意的 . 第一次调用DoSomething时,将正确创建AnotherClass中的数组 . 第二次调用DoSomething函数时,会分配一个新数组(取消分配旧数组) . 奇怪的是数组的成员也被释放,这导致firstPeopleArray将已释放的引用作为数组的成员 . 访问for循环中的成员会导致崩溃 .
我发现以下行是罪魁祸首:
for person: Person! in people {
将此行更改为以下内容可解决此问题:
for person: Person in people {
问题是,为什么?为什么解包符号(!)会以这样的方式影响引用,在这种方式中,当数组被释放并且在firstPeopleArray中明确地使用了引用时,系统认为它需要释放数组的成员?