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