Sobes.tech
Middle

Mis on automaatne linkide arvutamine?

sobes.tech AI

Vastus AI-lt

Automaatne viidete arvutamine (Automatic Reference Counting, ARC) on mäluhaldusmehhanism Swiftis ja Objective-C-s, mis jälgib ja vabastab automaatselt objekti jaoks eraldatud mälu. Iga klassi eksemplaril on viidete loendur, mis suureneb, kui luuakse tugev viide objekti juurde, ja väheneb, kui see eemaldatakse. Kui viidete loendur jõuab nulli, vabastab ARC automaatselt objekti ja selle kasutatud mälu.

ARC takistab mälulõhke ja topeltvabastust, lihtsustades mäluhaldust võrreldes käsitsi haldamisega (nagu Objective-C ilma ARC-ta).

On kolm viidetüüpi:

  1. Tugev (Strong): Suurendab objekti viidete loendurit. See on vaikimisi viidetüüp.
  2. Nõrk (Weak): Ei suurenda viidete loendurit. Kasutatakse tugevate viidete tsüklite vältimiseks, kui kaks objekti viitavad üksteisele tugevalt. Nõrk viide muutub nil, kui sellele viitav objekt vabastatakse. Määratletakse võtmesõnaga weak.
  3. Mittehooldatud (Unowned): Ei suurenda viidete loendurit ja alati omab väärtust. Kasutatakse, kui on teada, et viide alati viitab objekti, kuni see eksisteerib. Erinevalt weak-ist, mittehooldatud viide ei muutu nil-iks ja võib põhjustada vea, kui sellele püüda ligi pääseda pärast objekti vabastamist. Määratletakse võtmesõnaga unowned.

Tugeva tsükli näide:

class Human {
    let name: String
    var apartment: Apartment? // Tugev viide valikulisele Apartmentile
    init(name: String) {
        self.name = name
        print("\(name) on alustanud")
    }
    deinit {
        print("\(name) on lõpetanud")
    }
}

class Apartment {
    let unit: String
    var tenant: Human? // Tugev viide valikulisele Humanile
    init(unit: String) {
        self.unit = unit
        print("Korter \(unit) on alustanud")
    }
    deinit {
        print("Korter \(unit) on lõpetanud")
    }
}

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
// Mitte "John Appleseed on lõpetanud" ega "Korter 4A on lõpetanud" ei kuvata, kuna on tsükkel tugevate viidete tõttu

Tugeva tsükli lahendus weak kasutamisega:

class Human {
    let name: String
    var apartment: Apartment?
    init(name: String) {
        self.name = name
        print("\(name) on alustanud")
    }
    deinit {
        print("\(name) on lõpetanud")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Human? // Nõrk viide
    init(unit: String) {
        self.unit = unit
        print("Korter \(unit) on alustanud")
    }
    deinit {
        print("Korter \(unit) on lõpetanud")
    }
}

var john: Human?
var unit4A: Apartment?

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

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

john = nil // John vabastatakse, kuna tema viidete loendur on 0
unit4A = nil // Korter vabastatakse, kuna tema viidete loendur on 0