Sobes.tech
Middle

Ի՞նչ է unowned-ը Swift լեզվում և ինչպես է այն օգտագործվում:

sobes.tech AI

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

Անհատական հղում (թույլ անուղղակի սեփականություն) Swift-ում օգտագործվում է ուժեղ սեփականության ցիկլերը (retain cycles) խուսափելու համար, երբ երկու օբյեկտներ ուժեղորեն հղում են միմյանց, կանխելով նրանց ազատումը հիշողությունից:

unowned-ի առանձնահատկությունները՝

  • Համոզված է, որ այն օբյեկտը, որի վրա հղում է անում unowned-ը, միշտ գոյություն ունի այդ հղումից առաջ:
  • Եթե փորձեք մուտք գործել unowned հղում այն ​​ժամանակ, երբ կապված օբյեկտը արդեն ազատվել է, տեղի կունենա գործընթացի ժամանակի խափանում (runtime crash):
  • Օգտագործվում է, երբ հղվող օբյեկտի կյանքի ցիկլը չէ երկար այն օբյեկտից, որի վրա հղում է անում։ Այսինքն, unowned հղումը չի դարձնում օբյեկտը ուժեղ:

Օրինակ՝ փակման մեջ հղում օգտագործելու դեպքում:

class Customer {
    let name: String
    var card: CreditCard?

    init(name: String) {
        self.name = name
    }

    deinit {
        print("\(name) ազատվում է")
    }
}

class CreditCard {
    let number: UInt64
    unowned let customer: Customer // Unowned հղում Customer-ին

    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }

    deinit {
        print("Քարտ #\(number) ազատվում է")
    }
}

var john: Customer? // Օպցիոնալ Customer՝ ազատման հնարավորությամբ
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)

// Եթե նշանակենք nil, ապա Customer և Card ազատվում են,
// քանի որ չկա ուժեղ ցիկլ
john = nil 

Մյուս օրինակ՝ unowned-ի օգտագործում փակման մեջ:

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

    lazy var asHTML: () -> String = { [unowned self] in // `unowned self` օգտագործում
        if let text = self.text {
            return "<\(self.name)>\(text)</\(self.name)>"
        } else {
            return "<\(self.name) />"
        }
    }

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

    deinit {
        print("\(name) ազատվում է")
    }
}

var paragraph: HTMLElement? // Օպցիոնալ HTML տարր
paragraph = HTMLElement(name: "p", text: "hello world")
print(paragraph!.asHTML())

// Եթե նշանակենք nil, HTMLElement-ը ազատվում է, քանի որ փակումը չի պահում նրան ուժեղ
paragraph = nil

Ընտրությունը unowned և weak միջև կախված է նրանից, արդյոք հղումը կարող է լինել nil կյանքի ընթացքում։ Եթե հղումը ոչ մի ժամանակ չի կարող լինել nil նախքան օբյեկտի ազատումը, օգտագործեք unowned։ Եթե կարող է՝ օգտագործեք weak։