როგორ მუშაობს ავტომატური მეხსიერების მართვის (ARC) მექანიზმი Swift ენისთვის?
sobes.tech AI
პასუხი AI-სგან
ARC (Автоматикалык шилтемелерди эсептөө) автоматтык түрдө класстардын мисалдарына шилтемелерди көзөмөлдөп, башкаруу жүргүзөт. Ал мисалдын ээлеген эсебин бошотуп, эсебин бошотот, эгер ага күчтүү шилтемелер болбосо. ARC гана класстардын мисалдарында иштейт, структуралар же энумдар менен эмес, анткени алар маанилер түрү болуп саналат.
Мисалдар арасындагы үч түрдүү байланыс:
- Strong (Күчтүү): Мисалга шилтемени көбөйтөт. Бардык шилтемелер боюнча демейки күчтүү.
- Weak (Слабый): Шилтемени көбөйтпөйт. Күчтүү шилтемелер циклин алдын алуу үчүн колдонулат.
weakтиптеги шилтемелер ар дайым опционалдуу, анткени мисал кез келген учурда бошотулушу мүмкүн. - Unowned (Бошотулбаган): Шилтемени көбөйтпөйт жана байланыштуу мисалдын узактыгы учурдагыдан узунураак болот деп кепилдик берилген учурда колдонулат. Мажбур эмес, бирок бошотулган мисалга кирүү аракетинде иштөө ката чыгарат.
Күчтүү шилтемелер цикли пайда болот, эгер эки же андан көп мисал бири-бирине күчтүү шилтемелерди түзсө, бул ARCтин бошотулушун алдын алат. Бул циклдерди чечүү үчүн weak же unowned шилтемелер колдонулат.
Өлчөмдөрдүн мисалы:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
}
deinit { // бошотуу учурунда чакырылат
print("\(name) бошотулууда")
}
}
class Apartment {
let unit: String
var tenant: Person?
init(unit: String) {
self.unit = unit
}
deinit { // бошотуу учурунда чакырылат
print("Квартира \(unit) бошотулууда")
}
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil // Эч кандай чыгуу жок, анткени цикл түзүлдү
Циклдерди чечүү үчүн weak колдонуу:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
}
deinit {
print("\(name) бошотулууда")
}
}
class Apartment {
let unit: String
weak var tenant: Person? // Слабое шилтемени колдонуу
init(unit: String) {
self.unit = unit
}
deinit {
print("Квартира \(unit) бошотулууда")
}
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // Person бошотулду
unit4A = nil // Apartment бошотулду
Циклдерди чечүү үчүн unowned колдонуу:
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) бошотулууда")
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer // Бошотулбаган шилтеме
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Карта #\(number) бошотулууда")
}
}
var john: Customer?
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
john = nil // Customer жана CreditCard бошотулду
ARC жана аягында: Аягында, блоктор да циклер түзө алат, класстардын мисалдарын кармап калуу аркылуу. Бул циклдерди алдын алуу үчүн [weak self] же [unowned self] колдонулат:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { // lazy, self колдонууга мүмкүндүк берүү үчүн
[unowned self] in // кармоо тизмеси
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) бошотулууда")
}
}
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "салам, дүйнө")
print(paragraph!.asHTML())
paragraph = nil // HTMLElement бошотулду