Swift Academy · Oppitunti

Sieppauslistat ja weak self

Vältä säilytyskehiä rakenteella [weak self].

Oppitunti 3/413 vaihetta

Sieppauslistat ja weak self on ilmainen Swift Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Swift Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Swift Academy-kurssilla on yhteensä 4 oppituntia.

Retain cycle -riskin vaara

Kun olio tallentaa escaping-sulkeuman, joka kaappaa self-olion vahvana viitteenä, ne pitävät toisensa ikuisesti elossa — syntyy retain cycle, joka aiheuttaa muistivuodon.

Vahva viitesykli

Sulkeuma kaappaa self-olion vahvana viitteenä, ja self säilyttää sulkeuman — kumpaakaan ei koskaan vapauteta:

class Owner {
    var onEvent: (() -> Void)?
    func setup() {
        onEvent = { print(self.describe()) }  // strong self -> cycle
    }
    func describe() -> String { "Owner" }
}
let o = Owner(); o.setup()
o.onEvent?()  // "Owner"  (but leaks)

Capture-listat

Sulkeuman alussa oleva capture-list, { [weak self] in ... }, hallitsee sitä, miten kukin kaapattu viite säilytetään: weak- tai unowned-viitteenä vahvan viitteen sijaan.

Syklin katkaiseminen weak self -viitteellä

[weak self] kaappaa self-olion valinnaisena viitteenä, joka ei pidä sitä elossa:

class Owner {
    var onEvent: (() -> Void)?
    func setup() {
        onEvent = { [weak self] in
            print(self?.describe() ?? "gone")
        }
    }
    func describe() -> String { "Owner" }
}
let o = Owner(); o.setup()
o.onEvent?()  // "Owner"  (no cycle)

weak tekee self-oliosta valinnaisen

[weak self]-kaappauksessa self muuttuu tyypiksi Self?, joten purkakaa se:

class Worker {
    var tag = "W"
    lazy var job: () -> Void = { [weak self] in
        guard let self = self else { return }
        print(self.tag)
    }
}
let w = Worker()
w.job()  // "W"

guard let self -malli

Sidokaa self uudelleen heti alussa, jotta sulkeuman loppuosa käyttää vahvaa, ei-valinnaista viitettä:

class Service {
    var name = "S"
    lazy var run: () -> Void = { [weak self] in
        guard let self else { return }
        print(self.name)
        print("still \(self.name)")
    }
}
Service().run()  // "S" / "still S"

weak ja unowned

weak tuottaa valinnaisen viitteen ja on turvallinen, jos olio saattaa olla jo poistunut. unowned ei ole valinnainen ja on nopeampi, mutta aiheuttaa kaatumisen, jos sitä käytetään olion vapauttamisen jälkeen — käyttäkää sitä vain, kun self-olion tiedetään elävän sulkeumaa pidempään.

unowned-viitteen käyttäminen

Valitkaa unowned, kun sulkeuma ei voi elää self-oliota pidempään:

class Timer2 {
    var ticks = 0
    lazy var tick: () -> Void = { [unowned self] in
        self.ticks += 1
    }
}
let t = Timer2()
t.tick(); t.tick()
print(t.ticks)  // 2

Tiettyjen ominaisuuksien kaappaaminen

Kaapatkaa vain tarvitsemanne sen sijaan, että kaappaisitte koko self-olion — joskus tämä estää syklin kokonaan:

class VM {
    let id = 42
    lazy var printer: () -> Void = { [id] in print(id) }
}
VM().printer()  // 42

Non-escaping ei tarvitse weak-viitettä

Synkroniset non-escaping-sulkeumat, kuten map, eivät aiheuta syklejä, joten self-olion kaappaaminen vahvana viitteenä on niissä turvallista:

class Calc {
    let factor = 3
    func scale(_ xs: [Int]) -> [Int] {
        xs.map { $0 * self.factor }   // safe, non-escaping
    }
}
print(Calc().scale([1, 2]))  // [3, 6]

Nyrkkisääntö

Käyttäkää [weak self]-kaappausta tallennetuissa tai escaping-sulkeumissa, jotka viittaavat self-olioon. Käyttäkää unowned-viitettä vain, kun self-olion elossaolo on taattu. Älkää käyttäkö capture-listoja non-escaping-sulkeumissa.

class P {
    var n = "P"
    var stored: (() -> Void)?
    func arm() { stored = { [weak self] in print(self?.n ?? "-") } }
}
let p = P(); p.arm(); p.stored?()  // "P"

Pikakysymys

Miksi tallennetussa escaping-sulkeumassa käytetään [weak self]-kaappausta?

Kertaus

Opitte capture-listat:

  • Vahvana viitteenä kaapattu self-olio tallennetussa escaping-sulkeumassa luo retain cyclen eli muistivuodon
  • [weak self] katkaisee syklin; self muuttuu valinnaiseksi — käyttäkää guard let self-rakennetta
  • unowned ei ole valinnainen ja on nopeampi, mutta aiheuttaa kaatumisen, jos self-olio on poistunut
  • Non-escaping-sulkeumat eivät tarvitse capture-listoja

Seuraavaksi: autoclosuret.

Aloita maksutta

Opi Swift tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
122
Oppitunnit
409

Usein kysytyt kysymykset

Onko oppitunti ”Sieppauslistat ja weak self” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Swift Academy-oppimispolun 3 oppituntia, myös oppitunnin “Sieppauslistat ja weak self”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Swift Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Sieppauslistat ja weak self”?

Vältä säilytyskehiä rakenteella [weak self]. Harjoittelet Swift Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Swift Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Swift Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Sieppauslistat ja weak self”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Swift Academy-oppitunnilla?

Kyllä. Jokainen Swift Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Arvojen sieppaaminen viittauksina
  2. Escaping-sulkeumat
  3. Sieppauslistat ja weak self
  4. Automaattiset sulkeumat
← Takaisin: Swift Academy