Sobes.tech
Junior — Middle

Előfordulhatnak nehézségek vagy váratlan viselkedések, ha egy osztály belső lezárása hozzáfér az osztály módszereihez vagy tulajdonságaihoz?

sobes.tech MI

Válasz az MI-től

Igen, amikor Swiftben egy osztályon belüli zárványokat (closures) használunk a metódusok vagy tulajdonságok elérésére, előfordulhatnak nehézségek, amelyek a self elfogásával és a lehetséges retention cycle (tartási ciklus) problémáival kapcsolatosak.

Ha egy zárvány self-t fog meg anélkül, hogy gyenge ([weak self]) vagy nem szóbeli ([unowned self]) hivatkozást használna, akkor ez megakadályozhatja az osztály példányának memória felszabadítását, mivel a zárvány erős hivatkozást tart self-re, és self tarthatja a zárványt.

Probléma példája:

class MyClass {
    var closure: (() -> Void)?
    var value = 10

    func setupClosure() {
        closure = {
            print(self.value) // self elfogása
        }
    }

    deinit {
        print("MyClass felszabadult")
    }
}

var obj: MyClass? = MyClass()
obj?.setupClosure()
obj = nil // A MyClass nem kerül felszabadításra retention cycle miatt

Ennek elkerülése érdekében gyenge hivatkozást használunk:

closure = { [weak self] in
    guard let self = self else { return }
    print(self.value)
}

Ezért fontos gondosan kezelni a self elfogását osztályokon belüli zárványokban, hogy elkerüljük a memória szivárgásokat és a nem várt viselkedést.