Sobes.tech
Middle

გვითხარით iOS-ის მეხსიერების მართვის შესახებ.

sobes.tech AI

პასუხი AI-სგან

iOS автоматтык эс тутумду башкаруу үчүн ARC (Automatic Reference Counting) колдонуп жатат. ARC автоматтык түрдө объекттерди бошотот, алардын шилтемелери жок болгондо:

Негизги түшүнүктөр:

  • Күчтүү шилтеме: Объекттин шилтемелер санын көбөйтөт. Объект бошотулбайт, эгерде ага күчтүү шилтемелер болсо.
  • Слаб шилтеме: шилтеме санын көбөйтпөйт. Выкарыстылат күчтүү шилтемелердин циклин алдын алуу үчүн. Объектке шилтеме, ал бошотулушу мүмкүн. Эгер объект бошотулса, слаб шилтеме nil болот.
  • Unowned шилтеме: слаб шилтеме сыяктуу, бирок объект бошотулганда nil болбойт. Объекттин өмүрү бирдей же узак болсо колдонулат. Unowned шилтеме nil болбойт, жана эгер объект бошотулса, ката чыгат.

Күчтүү шилтемелер цикли (Retain Cycles): эки же андан көп объекттин бири-бирине күчтүү шилтемелери бар болсо, ал алардын бошотулушуна тоскоол болот. Бул weak же unowned шилтемелер менен чечилет.

Мисал:

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("Apartment \(unit) ишке киришти")
    }

    deinit {
        print("Apartment \(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("Apartment \(unit) ишке киришти")
    }

    deinit {
        print("Apartment \(unit) жыйынтыкталды")
    }
}

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

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

john = nil
unit4A = nil
// Эки объект да туура жыйынтыкталат

Unowned vs Weak:

  • weak колдон, эгер шилтеме nil болушу мүмкүн болсо (объект биринчи бошотулушу мүмкүн)
  • unowned колдон, эгер шилтеме дайыма мааниге ээ болсо (объекттин өмүрү бирдей же узак)

Closure жана циклы шилтемелер:

Closure-лар объекттерге шилтемелерди захват кылышы мүмкүн, бул күчтүү циклы түзөт. Бул 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): Эстутумдун бөлүштүрүлүшү жана бошотулушун көзөмөлдөйт, унутулуп калган жерлерди табат.