how to make deinit take effect in swift

2019-05-21 18:13发布

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
    }
}

2条回答
冷血范
2楼-- · 2019-05-21 18:59
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.

查看更多
爷的心禁止访问
3楼-- · 2019-05-21 19:11

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")
   }

}
查看更多
登录 后发表回答