Sobes.tech
Middle

Šta je automatsko brojanje linkova?

sobes.tech АИ

Одговор од АИ

Автоматско броење референци (Automatic Reference Counting, ARC) је механизам за управљање меморијом у Swift-у и Objective-C-у који аутоматски прати и ослобађа меморију додељену за објекте. Свакој инстанци класе додељен је бројач референци који се повећава при стварању јаке референце на објекат и смањује при њеном уклањању. Када бројач референци достигне нулу, ARC аутоматски ослобађа објекат и меморију коју заузима.

ARC спречава цурење меморије и дупло ослобађање, поједностављујући управљање меморијом у поређењу са ручним управљањем (као у Objective-C без ARC).

Постоје три типа референци:

  1. Strong (Јак): Повећава бројач референци објекта. Ово је подразумевани тип референце.
  2. Weak (Слаб): Не повећава бројач референци. Користи се за спречавање циклуса јаке референце, када два објекта међусобно реферирају један другог. Слаба референца постаје nil ако је објекат на који указује ослобођен. Дефинише се кључном речи weak.
  3. Unowned (Безвласни): Не повећава бројач референци и увек има вредност. Користи се када је познато да ће референца увек указивати на објекат док он постоји. За разлику од weak, безвласна референца не постаје nil и може изазвати пад програма ако покушате да приступите објекту након његовог ослобађања. Дефинише се кључном речи unowned.

Пример циклуса јаке референце:

class Human {
    let name: String
    var apartment: Apartment? // Јака референца на опциони Apartment
    init(name: String) {
        self.name = name
        print("\(name) се иницијализује")
    }
    deinit {
        print("\(name) се деиницијализује")
    }
}

class Apartment {
    let unit: String
    var tenant: Human? // Јака референца на опциони Human
    init(unit: String) {
        self.unit = unit
        print("Апартман \(unit) се иницијализује")
    }
    deinit {
        print("Апартман \(unit) се деиницијализује")
    }
}

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
// Ни "John Appleseed се деиницијализује", ни "Apartment 4A се деиницијализује" неће бити приказано због циклуса јаке референце

Решење проблема циклуса јаке референце коришћењем weak:

class Human {
    let name: String
    var apartment: Apartment?
    init(name: String) {
        self.name = name
        print("\(name) се иницијализује")
    }
    deinit {
        print("\(name) се деиницијализује")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Human? // Слаба референца
    init(unit: String) {
        self.unit = unit
        print("Апартман \(unit) се иницијализује")
    }
    deinit {
        print("Апартман \(unit) се деиницијализује")
    }
}

var john: Human?
var unit4A: Apartment?

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

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

john = nil // Јохн се ослобађа, јер му бројач референци постаје 0
unit4A = nil // Апартман се ослобађа, јер му бројач референци постаје 0