Sobes.tech
Middle

Ի՞նչ է unowned-ը։

sobes.tech AI

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

unowned — դա Swift-ում թանկագին հղում հայտարարելու հիմնական բառ է: Այն օգտագործվում է, երբ երկու օբյեկտ ունեն ուժեղ կապ և նրանց կյանքի ցիկլերը կախված են միմյանցից, բայց մենք ուզում ենք խուսափել ցիկլային հղումներից, որոնք կարող են խանգարել հիշողության ազատմանը:

Հիմնական հատկություններ և տարբերություններ weak-ի հետ:

  • Ոչ ընտրովի: unowned հղումը հաստատապես չի լինի nil ողջ օբյեկտի կյանքի ընթացքում, որի վրա այն հղում է:
  • Հզոր կապ: Օգտագործվում է, երբ մեկ օբյեկտը պատկանում է մյուսին, և նրանք միշտ միասին գոյություն ունեն:
  • Համար ազատման: Եթե unowned հղում ունեցող օբյեկտը ազատվի հիշողությունից այն ժամանակ, երբ հղումը օգտագործվում է, դա կհանգեցնի ծրագրի կոտրմանը (runtime error): Պետք է համոզվեք, որ հղում ունեցող օբյեկտը գոյություն ունի ավելի երկար, քան հղումը:
  • Հայտում: Հաճախ օգտագործվում է դելեգատների համար, երբ դելեգատը միշտ երկար է ապրում, քան այն օբյեկտը, որը նրան կանչում է, կամ փակման մեջ, որպեսզի խուսափել ցիկլային հղումներից self-ին, երբ փակումը չի բռնում ուժեղ հղում self-ին:

Օրինակ օգտագործումը փակման մեջ:

// swift
class MyClass {
    var name: String
    var closure: (() -> Void)?

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

    func setupClosure() {
        closure = { [unowned self] in // Օգտագործում է unowned self
            print("My name is \(self.name)")
        }
    }

    deinit {
        print("\(name) deinitialized")
    }
}

Օրինակ օգտագործումը դելեգատով (համենայն դեպս weak-ը հաճախ օգտագործվում է դելեգատների համար, unowned-ը նույնպես հնարավոր է, եթե դելեգատը համոզվածորեն երկար է ապրում):

// swift
protocol MyDelegate: AnyObject { // AnyObject պահանջում է հղումային տիպ
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // unowned հղում դելեգատին

    init(delegate: MyDelegate) {
        self.delegate = delegate
    }

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource deinitialized")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

    override init() {
        super.init()
        dataSource = DataSource(delegate: self)
    }

    func doSomething() {
        print("Delegate method called")
    }

    deinit {
        print("MyController deinitialized")
    }
}

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