Ի՞նչ է ավտոմատ հղումների հաշվարկը։
sobes.tech AI
Պատասխան AI-ից
Ավտոմատ ռեֆերանսների հաշվարկը (Automatic Reference Counting, ARC) մեխանիզմ է հիշողության կառավարման Swift և Objective-C-ում, որը ավտոմատ կերպով հետևում և ազատում է օբյեկտների համար հատկացված հիշողությունը: Յուրաքանչյուր դասի օրինակ ունի ռեֆերանսների հաշվիչ, որը մեծանում է, երբ ստեղծվում է ուժեղ ռեֆերանս օբյեկտի վրա և նվազում է, երբ այն հեռացվում է: Երբ ռեֆերանսների հաշվիչը հասնում է զրոյի, ARC-ը ավտոմատ կերպով ազատում է օբյեկտը և այն զբաղեցրած հիշողությունը:
ARC-ը կանխում է հիշողության արտահոսքերը և կրկնակի ազատումը, պարզեցնելով հիշողության կառավարմանը՝ համեմատած ձեռքով կառավարմամբ (օրինակ՝ Objective-C-ում առանց ARC-ի):
Կան երեք տեսակի ռեֆերանսներ:
- Strong (ուժեղ): մեծացնում է օբյեկտի ռեֆերանսների հաշվիչը: Սա հիմնական ռեֆերանսի տեսակն է:
- Weak (թույլ): չի մեծացնում ռեֆերանսների հաշվիչը: Օգտագործվում է ուժեղ ռեֆերանսային ցիկլերի կանխարգելման համար, երբ երկու օբյեկտներ միմյանց վրա ուժեղ ռեֆերանսներ ունեն: Թույլ ռեֆերանսը
nilկդառնա, եթե այն օբյեկտը, որի վրա ցույց է տալիս, ազատվի: Դիֆայնվում էweakբանալիով: - 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("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 // Apartment-ը ազատվում է, քանի որ նրա ռեֆերանսների հաշվիչը դարձավ 0