Sobes.tech
Middle

Kā novērst atmiņas noplūdi jūsu projektos?

sobes.tech AI

Atbilde no AI

Es izmantoju vairākus pieejas:

  1. ARC (Automatic Reference Counting): Tas ir galvenais atmiņas pārvaldības mehānisms Swift un Objective-C. Tas automātiski skaita atsauces uz objektu un atbrīvo tos, kad atsauču skaits sasniedz nulli.
  2. Vairāku stipru atsauču ciklu novēršana: Šis ir visbiežākais atmiņas noplūdes iemesls. Es izmantoju weak vai unowned atsauces, lai pārtrauktu ciklus. Tas galvenokārt notiek ar deleģentiem un aizvērtajiem.
  3. Profilēšanas rīki: Es regulāri izmantoju Xcode rīkus, piemēram, Instruments (Allocator, Leaks), lai atklātu noplūdes vietas.
  4. Aizvērtu pārbaude: Es rūpīgi pārbaudu aizvērtos, īpaši, ja tie satur self, izmantojot [weak self] vai [unowned self] sarakstus.
  5. Paziņojumu atcelšana: Es atceļu paziņojumu centru (NotificationCenter) un KVO novērotājus, kad objekti tiek iznīcināti.
  6. Novērotāju un taimeru dzēšana: Es atslēdzu un nulleju invalidate taimerus un noņemu novērotājus, kad tie vairs nav nepieciešami.
  7. Resursu pārvaldība: Es pareizi pārvaldu resursus, piemēram, failus, soketus un datu bāzes, savlaicīgi tos aizverot un atbrīvojot.
  8. Koda pārskatīšana: Es regulāri veicu koda pārskatīšanu, tostarp, lai atklātu potenciālas atmiņas pārvaldības problēmas.

Piemērs [weak self] izmantošanai aizvērtā:

class DataFetcher {
    var completionHandler: (() -> Void)?

    func fetchData() {
        // Izmanto `weak self`, lai novērstu stipru ciklu
        DispatchQueue.global().async { [weak self] in
            // Datu iegūšanas imitācija
            sleep(1)

            DispatchQueue.main.async {
                // Pārbaude, vai `self` nav nil
                self?.completionHandler?()
            }
        }
    }
}

class ViewController {
    var fetcher: DataFetcher?

    func setupFetcher() {
        fetcher = DataFetcher()
        fetcher?.completionHandler = {
            // Šeit `self` tagad var būt vājš, ja fetcher vēl pastāv
            print("Data fetched in ViewController")
        }
    }

    deinit {
        print("ViewController iznīcināts")
    }
}

Piemērs [weak] izmantošanai deleģētājam:

protocol DataProcessorDelegate: AnyObject { // AnyObject nodrošina atsauces tipu un novērš stiprus ciklus ar vērtību tipiem
    func processData(_ data: String)
}

class DataProcessor {
    weak var delegate: DataProcessorDelegate? // Izmanto `weak` deleģētājam

    func process(_ data: String) {
        delegate?.processData(data)
    }
}

class AnotherViewController: DataProcessorDelegate {
    let processor = DataProcessor()

    init() {
        processor.delegate = self
    }

    func processData(_ data: String) {
        print("Datu apstrāde: \(data)")
    }

    deinit {
        print("CitsViewController iznīcināts")
    }
}