Sobes.tech
Middle

Ինչպե՞ս կարելի է կանխել iOS-ում պահպանումի ցիկլը (retain cycle):

sobes.tech AI

Պատասխան AI-ից

Կայքերի պահպանումը կանխվում է ճիշտ օգտագործելով թույլ (weak) կամ անշրջանցելի (unowned) հղումները:

Թույլ հղումներ (weak):

  • Չավելացնում են օբյեկտի հղումների հաշվիչը:
  • Նուլ (կարող է դառնալ nil):
  • Օգտագործվում են, երբ մեկ օբյեկտ կարող է գոյություն ունենալ անկախ մյուսից (օրինակ, դելեգատ):
class DelegateExample {
    weak var delegate: SomeDelegateType? // Թույլ հղում դելեգատին
}

Անշրջանցելի (unowned) հղումներ:

  • Չավելացնում են օբյեկտի հղումների հաշվիչը:
  • Գаранտավորված չեն nil լինել:
  • Օգտագործվում են, երբ մեկ օբյեկտը հստակ պատկանում է մյուսին, բայց կախված օբյեկտը կարող է գոյություն ունենալ միայն սեփականատիրոջ հետ միասին (օրինակ, փակագծեր, self-ին բռնագրավող class-ում, որտեղ փակագիծը հստակ "պատկանում" է դասի օրինակին): Երբ մուտք գործելով unowned հղում, եթե օբյեկտը արդեն ազատ է արձակվել, տեղի է ունենում ժամանակային սխալ:
class Owner {
    var closure: (() -> Void)?

    func setupClosure() {
        closure = { [unowned self] in // Անշրջանցելի հղում self-ին
            // Օգտագործում self
            print("Օգտագործում unowned self")
        }
    }
}

Օգտագործում փակագծերում: Փակագծերը կարող են առաջացնել պահպանումների շրջաններ, եթե նրանք բռնում են դասի օրինակները ուժեղ հղումով, և այդ դասի օրինակն էլ պարունակում է ուժեղ հղում փակագծին: Դրա կանխարգելման համար օգտագործվում են բռնագրավման ցանկեր (capture lists) փակագծի սկզբում:

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

    lazy var asHTML: () -> String = { [weak self] in // Թույլ հղում self-ին
        guard let strongSelf = self else {
            return "" // Երբեմն, երբ self արդեն `nil`
        }
        if let text = strongSelf.text {
            return "<\(strongSelf.name)>\(text)</\(strongSelf.name)>"
        } else {
            return "<\(strongSelf.name)/>"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) դադարեցվում է")
    }
}

Ընտրությունը weak և unowned միջև կախված է հարաբերությունների սիմանտիկայից:

  • weak: երբ հղումը կարող է դառնալ nil կյանքի ընթացքում:
  • unowned: երբ հղվող օբյեկտը երաշխավորված է երկար կամ հավասարապես երկար լինել այն օբյեկտից, որը հղում է անում, և հղումը երբեք չի դառնա nil: