Sobes.tech
Middle

Kuidas vältida iOS-is hoidmisringi (retain cycle)?

sobes.tech AI

Vastus AI-lt

Hoidmiskeerud nõuavad õiget kasutamist nõrkade (weak) või tingimusteta (unowned) viidete kaudu, et vältida tsüklilisi hoidmisi.

Nõrgad viited (weak):

  • Ei suurenda objekti viidete loendurit.
  • Võivad muutuda nil-iks.
  • Kasutatakse, kui üks objekt võib eksisteerida sõltumatult teisest (näiteks, delegeerija).
class DelegateExample {
    weak var delegate: SomeDelegateType? // Nõrk viide delegeerijale
}

Tingimusteta (unowned) viited:

  • Ei suurenda objekti viidete loendurit.
  • On garanteeritud, et ei ole nil.
  • Kasutatakse, kui üks objekt omab selgelt teist, kuid sõltuv objekt võib eksisteerida ainult koos omanikuga (näiteks, sulgudes, haarates self klassis, kus sulg selgelt "kuulub" klassi eksemplarile). unowned viite kasutamisel, kui objekt on juba vabastatud, tekib jooksuaegne viga.
class Owner {
    var closure: (() -> Void)?

    func setupClosure() {
        closure = { [unowned self] in // Tingimusteta hoidmatu viide self-ile
            // Self kasutamine
            print("Kasutades unowned self")
        }
    }
}

Kasutamine sulgudes: Sulgudes võivad tekitada hoidmistsüklid, kui nad haaravad klassi eksemplare tugevate viidetega, ning see eksemplar sisaldab ka tugevat viidet sulgudele. Selle vältimiseks kasutatakse haaramisnimekirju (capture lists) sulgude alguses:

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

    lazy var asHTML: () -> String = { [weak self] in // Nõrk viide self-ile
        guard let strongSelf = self else {
            return "" // Kui self on juba `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) deaktiveeritakse")
    }
}

Valik weak ja unowned vahel sõltub objektide vahelise semantika suhte olemusest:

  • weak: kui viide võib muutuda nil-iks objekti elutsükli jooksul.
  • unowned: kui objekt, millele viidatakse, eksisteerib kindlalt kauem või sama kaua kui sellele viitav objekt ning viide ei muutu kunagi nil-iks.