Middle
Kako sprečavate curenje memorije u vašim projektima?
sobes.tech АИ
Одговор од АИ
Koristim nekoliko pristupa:
- ARC (Automatic Reference Counting): To je glavni mehanizam za upravljanje memorijom u Swiftu i Objective-C. Automatski broji reference na objekte i oslobađa ih kada broj referenci padne na nulu.
- Izbegavanje ciklusa sa jakim referencama: Ovo je najčešći uzrok curenja memorije. Koristim
weakiliunownedreference za prekidanje ciklusa. Najčešće se dešava pri radu sa delegatima i zatvaranjima. - Alati za profilisanje: Redovno koristim alate iz Xcode, kao što su Instruments (Allocator, Leaks), za otkrivanje mesta curenja.
- Provera zatvaranja: Pažljivo proveravam zatvaranja, posebno pri hvatanju self, koristeći liste hvatanja
[weak self]ili[unowned self]. - Odjavljivanje od obaveštenja: Odjavljujem se od
NotificationCenteri posmatrača KVO pri uništenju objekata. - Uklanjanje posmatrača i tajmera: Isključujem i nuliram invalidate tajmere i uklanjam posmatrače kada više nisu potrebni.
- Rad sa resursima: Ispravno upravljam resursima kao što su fajlovi, soketi i baze podataka, pravovremeno ih zatvarajući i oslobađajući.
- Recenzije koda: Redovno vršim revizije koda, uključujući s ciljem otkrivanja potencijalnih problema sa upravljanjem memorijom.
Primer korišćenja [weak self] u zatvaranju:
class DataFetcher {
var completionHandler: (() -> Void)?
func fetchData() {
// Korišćenje weak self za sprečavanje jakog ciklusa
DispatchQueue.global().async { [weak self] in
// Simulacija dobijanja podataka
sleep(1)
DispatchQueue.main.async {
// Provera na nil pre korišćenja self
self?.completionHandler?()
}
}
}
}
class ViewController {
var fetcher: DataFetcher?
func setupFetcher() {
fetcher = DataFetcher()
fetcher?.completionHandler = {
// Ovde self sada može biti slab, ako fetcher i dalje postoji
print("Data fetched in ViewController")
}
}
deinit {
print("ViewController deinitialized")
}
}
Primer korišćenja weak za delegata:
protocol DataProcessorDelegate: AnyObject { // AnyObject obezbeđuje referentni tip i sprečava jake cikluse sa vrednosnim tipovima
func processData(_ data: String)
}
class DataProcessor {
weak var delegate: DataProcessorDelegate? // Korišćenje weak za delegata
func process(_ data: String) {
delegate?.processData(data)
}
}
class AnotherViewController: DataProcessorDelegate {
let processor = DataProcessor()
init() {
processor.delegate = self
}
func processData(_ data: String) {
print("Processing data: \(data)")
}
deinit {
print("AnotherViewController deinitialized")
}
}