Sobes.tech
Middle

дар бораи идоракунии хотира дар iOS нақл кунед.

sobes.tech AI

Ҷавоб аз AI

iOS выкарыстоўвае аўтаматычнае кіраванне памяццю з дапамогай ARC (Automatic Reference Counting). ARC аўтаматычна вызваляе аб'екты, калі на іх больш няма спасылак.

Асноўныя канцэпцыі:

  • Моцная спасылка: Павышае лічыльнік спасылак на аб'ект. Аб'ект не будзе вызвалены, пакуль на яго ёсць моцныя спасылкі.
  • Слабая спасылка: не павышае лічыльнік спасылак. Выкарыстоўваецца для прадухілення цыклаў моцных спасылак. Спасылаецца на аб'ект, які можа быць вызвалены. Калі аб'ект вызваляецца, слабая спасылка становіцца nil.
  • Непарушная спасылка: падобна на слабую, не павышае лічыльнік спасылак. Выкарыстоўваецца, калі аб'ект, на які спасылаюцца, мае той жа або больш працяглы жыццёвы цыкл. Непарушная спасылка не становіцца nil пры вызваленні аб'екта. Пры спробе доступу да вызваленага аб'екта праз непарушную спасылку ўзнікае памылка выканання.

Цыклы моцных спасылак (Retain Cycles): ўзнікаюць, калі два або больш аб'ектаў маюць моцныя спасылкі адзін на аднаго, што не дазваляе ім быць вызваленымі. Вырашаюцца з дапамогай слабых або непарушных спасылак.

Прыклад цыклу моцных спасылак і яго рашэнне:

class Person {
    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: Person? // Выкарыстанне слабой спасылкі для прадухілення цыклу

    init(unit: String) {
        self.unit = unit
        print("Кватэра \(unit) ініцыялізуецца")
    }

    deinit {
        print("Кватэра \(unit)  дэініцыялізуецца")
    }
}

var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = 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
        print("\(name) ініцыялізуецца")
    }

    deinit {
        print("\(name)  дэініцыялізуецца")
    }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // Выкарыстанне слабой спасылкі для прадухілення цыклу

    init(unit: String) {
        self.unit = unit
        print("Кватэра \(unit) ініцыялізуецца")
    }

    deinit {
        print("Кватэра \(unit)  дэініцыялізуецца")
    }
}

var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")

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

john = nil
unit4A = nil
// Абодва аб'екты дэініцыялізуюцца правільна

Непарушныя vs Слабыя:

  • Выкарыстоўвай weak, калі спасылка можа стаць nil (аб'ект можа быць вызвалены першым).
  • Выкарыстоўвай unowned, калі спасылка заўсёды будзе мець значэнне (аб'ект, на які спасылаюцца, мае той жа або больш працяглы жыццёвы цыкл).

Закрыцці і цыклы спасылак:

Закрыцці могуць захопліваць спасылкі на аб'екты, ствараючы цыклы моцных спасылак. Гэта вырашаецца з дапамогай спісу захопу (capture list).

Прыклад:

class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = {
        [weak self] in // Захоп `self` слабай спасылкай
        guard let self = self else {
            return ""
        }
        var html = "<\(self.name)"
        if let text = self.text {
            html += ">\(text)</\(self.name)>"
        } else {
            html += " />"
        }
        return html
    }

    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
// Аб'ект дэініцыялізаваны

Адладка праблем з памяццю:

  • Memory Graph Debugger: У Xcode дазваляе візуалізаваць сувязі паміж аб'ектамі і выяўляць цыклы моцных спасылак.
  • Instruments (Allocations, Leaks): Інструменты для маніторынгу размеркавання і вызвалення памяці, пошуку ўцечак.