I've created the following classes:
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)
}
}
}
}
As you can see, I've created a class called Person with two subclasses (Male and Female). I've also created a class (AnotherClass) that takes an array of Person classes and builds a new array of Male classes. As you can see, the
I've created the following code that builds the Person class arrays and calls the Another class function DoSomething. DoSomething allocates the array and filters the people array and appends only the Male classes to the secondPeopleArray member.
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()
}
As you can see, the DoSomething function is called twice. This is intentional. The first time DoSomething is called, the array in the AnotherClass is created properly. The second time the DoSomething function is called, a new array is allocated (which deallocates the old array). The strange thing is the members of the array are also deallocated, which results in firstPeopleArray to have deallocated references as members of the array. Accessing the member in the for loop results in a crash.
I've found the following line is the culprit:
for person: Person! in people {
Changing this line to the following fixes the issue:
for person: Person in people {
The question is, Why? Why would the unwrapping symbol (the !) affect the references in a way in which having the symbol there results in the system thinking it needs to deallocate the member of the array when the array is deallocated and the reference clearly is used in the firstPeopleArray?