Sobes.tech
Middle

Автоматтык шилтемелердин эсептелиши деген эмне?

sobes.tech AI

AIден жооп

Автоматтык шилтемелердин эсептелиши (Automatic Reference Counting, ARC) — Swift жана Objective-C тилдеринде колдонулган эс тутумду башкаруу механизми, ал автоматтык түрдө объекттер үчүн бөлүнгөн эс тутумду көзөмөлдөп, бошотуп турат. Ар бир класс мисалынын шилтемелердин санагыч бар, ал күчтүү шилтеменин түзүлүшүндө өсөт жана ал жоголгондо азаяды. Шилтемелердин санагыч нөлгө жеткенде, ARC автоматтык түрдө объектти жана анын ээлеген эс тутумду бошотот.

ARC эс тутумдун агып кетишин жана эки эсе бошотулушун алдын алат, эс тутумду башкарууну жөнөкөйлөтөт, мисалы Objective-C тилдеринде ARC жок учурдагыдай эмес.

Үч түрдүү шилтемелер бар:

  1. Strong (Күчтүү): Объекттин шилтемелердин санагычын көбөйтөт. Бул шилтеменин негизги түрү.
  2. Weak (Слаб): Шилтемелердин санагычын көбөйтпөйт. Бул күчтүү шилтемелер циклин алдын алуу үчүн колдонулат, эки объект бири-бирине күчтүү шилтемелер менен байланышканда. Слаб шилтеме nil болот, эгер ал шилтемелүү объект бошотулса. weak сөзү менен аныкталат.
  3. Unowned (Бейвласт): Шилтемелердин санагычын көбөйтпөйт жана дайыма мааниге ээ. Бул шилтеменин, эгер объект бар болсо, дайыма ошол объектке шилтеме жасай тургандыгын билгенде колдонулат. weak менен салыштырганда, unowned шилтемелер 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("Apartment \(unit) инициализацияланууда")
    }
    deinit {
        print("Apartment \(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("Apartment \(unit) инициализацияланууда")
    }
    deinit {
        print("Apartment \(unit) деструктуризацияланууда")
    }
}

var john: Human?
var unit4A: Apartment?

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

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

john = nil // John бошотулду, анткени анын шилтемелердин саны 0 болду
unit4A = nil // Апартмент бошотулду, анткени анын шилтемелердин саны 0 болду