问题
I have a Car class. Let's say a car goes to the junkyard, this car should no longer be counted in the total population. I have the deinit function, but how do I systematically remove a car from the car population? In other words, how do I get the deinit to take effect?
I have a class variable isJunk
but don't know how to use it to make this work.
class Car {
static var population: Int = 0
var isJunk: Bool = false
var color: String
var capacity: Int
var driver: Bool?
var carOn: Bool = false
init (carColor: String, carCapacity: Int) {
self.capacity = carCapacity
self.color = carColor
Car.population += 1
}
deinit {
Car.population -= 1
}
func startCar() {
self.carOn = true
}
}
回答1:
class Car {
static var population: Int = 0
init() {
Car.population += 1
}
deinit {
Car.population -= 1
}
}
var cars: [Car] = [Car(), Car()]
print("Population:", Car.population) // "Population: 2"
// now the second car is removed from array and we have no other references to it
// it gets removed from memory and deinit is called
cars.removeLast()
print("Population:", Car.population) // "Population: 1"
However, the same can be achieved just by asking the number of items in cars
array. And that's usually a better alternative than a private counter of instances.
To keep the items in memory you will always need some kind of register (e.g. an array) for them. And that register can keep them counted.
One possibility:
class CarPopulation {
var liveCars: [Car] = []
var junkCars: [Car] = []
}
Or you can keep them in one array and set junk
on the car and count non-junk cars when needed:
class CarPopulation {
var cars: [Car] = []
func liveCars() -> Int {
return self.cars.filter { !$0.junk }.count
}
}
There are many possibilities but extracting the counters to some other class that owns the cars is probably a better solution.
回答2:
The deinit is called when you deallocate your instance of Car
(when you entirely get rid of the instance of the object). When you put a Car
instance in the junkyard I don't think you want to get rid of the instance of Car
, you really just want to change its location. I would suggest a different function to handle changing the location of Car
.
Perhaps:
func changeLocation(newLocation: String) {
// Perhaps add an instance variable to 'remember' the location of the car
switch newLocation {
case "junkyard":
Car.population -= 1
default:
// Perhaps check whether previous location was Junkyard and increment
// counter if the Car is coming out of the Junkyard
print("Unrecognized location")
}
}
来源:https://stackoverflow.com/questions/38022278/how-to-make-deinit-take-effect-in-swift