Sobes.tech
Middle

Kas ir automātiskā saite skaitīšana?

sobes.tech AI

Atbilde no AI

Automātiskā atsauču skaitīšana (Automatic Reference Counting, ARC) ir atmiņas pārvaldības mehānisms Swift un Objective-C, kas automātiski uzrauga un atbrīvo atmiņu, kas piešķirta objektiem. Katram klases piemēram ir atsauču skaitītājs, kas palielinās, veidojot stipru atsauci uz objektu, un samazinās, to dzēšot. Kad atsauču skaitītājs sasniedz nulli, ARC automātiski atbrīvo objektu un atbrīvo to atmiņu.

ARC novērš atmiņas noplūdi un dubultu atbrīvošanu, vienkāršojot atmiņas pārvaldību salīdzinājumā ar manuālo pārvaldību (kā Objective-C bez ARC).

Ir trīs atsauču veidi:

  1. Stipra (Strong): Palielina objekta atsauču skaitītāju. Tā ir noklusējuma atsauces veids.
  2. Vāja (Weak): Nepalielina atsauču skaitītāju. Izmanto, lai novērstu stipro atsauču ciklus, kad divi objekti stipri atsaucas viens uz otru. Vāja atsauce kļūst par nil, ja objekts, uz kuru tā norāda, tiek atbrīvots. To definē ar atslēgvārdu weak.
  3. Nepārvaldīta (Unowned): Nepalielina atsauču skaitītāju un vienmēr ir ar vērtību. Izmanto, kad ir zināms, ka atsauce vienmēr norādīs uz objektu, kamēr tas pastāv. Atšķirībā no weak, nepārvaldīta atsauce nekļūst par nil un var izraisīt kļūmi, ja mēģina piekļūt objektam pēc tā atbrīvošanas. To definē ar atslēgvārdu unowned.

Stipro atsauču cikla piemērs:

class Human {
    let name: String
    var apartment: Apartment? // Stipra atsauce uz opcijas Apartment
    init(name: String) {
        self.name = name
        print("\(name) tiek inicializēts")
    }
    deinit {
        print("\(name) tiek de-inicializēts")
    }
}

class Apartment {
    let unit: String
    var tenant: Human? // Stipra atsauce uz opcijas Human
    init(unit: String) {
        self.unit = unit
        print("Dzīvoklis \(unit) tiek inicializēts")
    }
    deinit {
        print("Dzīvoklis \(unit) tiek de-inicializēts")
    }
}

var john: Human?
var unit4A: Apartment?

john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

john = nil
unit4A = nil
// Nekas no "John Appleseed tiek de-inicializēts" vai "Dzīvoklis 4A tiek de-inicializēts" netiks izvadīts, jo ir stiprs cikls

Risinājums stipro atsauču ciklam ar weak:

class Human {
    let name: String
    var apartment: Apartment?
    init(name: String) {
        self.name = name
        print("\(name) tiek inicializēts")
    }
    deinit {
        print("\(name) tiek de-inicializēts")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Human? // Vāja atsauce
    init(unit: String) {
        self.unit = unit
        print("Dzīvoklis \(unit) tiek inicializēts")
    }
    deinit {
        print("Dzīvoklis \(unit) tiek de-inicializēts")
    }
}

var john: Human?
var unit4A: Apartment?

john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

john = nil // John tiek de-inicializēts, jo viņa atsauces skaitītājs ir 0
unit4A = nil // Dzīvoklis tiek de-inicializēts, jo viņa atsauces skaitītājs ir 0