რა არის ავტომატური ბმულების გამოთვლა?
sobes.tech AI
პასუხი AI-სგან
ავტომატური მითითებების გამოთვლა (Automatic Reference Counting, ARC) არის მეხსიერების მართვის მექანიზმი Swift და Objective-C-ში, რომელიც ავტომატურად აკონტროლებს და გათავისუფლებს ობიექტებისთვის გამოყოფილ მეხსიერებას. თითოეულ კლასის მაგალითს აქვს მითითებების გამოთვლის გამოთვლილი, რომელიც იზრდება, როდესაც ქმნიან ძლიერ მითითებას ობიექტზე და მცირდება, როდესაც ის წაიშლება. როდესაც გამოთვლის გამოთვლილი მიაღწევს ნულს, ARC ავტომატურად გათავისუფლებს ობიექტს და მის მეხსიერებას.
ARC თავიდან აცილებს მეხსიერების გაჟონვას და ორმაგ გათავისუფლებას, მარტივს ხდის მეხსიერების მართვას, შედარებით ხელით მართვის (მაგალითად Objective-C-ში, ARC-ის გარეშე).
არსებობს სამი ტიპის მითითებები:
- Strong (ძლიერი): ზრდის ობიექტის მითითებების გამოთვლის გამოთვლას. ეს არის ნაგულისხმევი ტიპი.
- Weak (სუსტი): არ ზრდის გამოთვლის გამოთვლას. გამოიყენება ძლიერი მითითებების ციკლების თავიდან ასაცილებლად, როდესაც ორი ობიექტი ერთმანეთზე ძლიერად მითითებულია. სუსტი მითითება ხდება
nil, თუ მითითებული ობიექტი გათავისუფლდა. განსაზღვრულია სიტყვითweak. - 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