Perché [weak self] o [unowned self] non sono necessari nella coda delle operazioni?
Il Ottobre 5, 2021 da adminQuesta è una lista di cattura di Swift e come può essere utilizzata per evitare il ciclo di conservazione, non posso fare a meno di notare qualcosa di sconcertante su OperationQueue: non ha bisogno di ` o ` per prevenire perdite di memoria.
class SomeManager { let queue = OperationQueue() let cache: NSCache = { () -> NSCache<AnyObject, AnyObject> in let cache = NSCache<AnyObject, AnyObject>() cache.name = "huaTham.TestOperationQueueRetainCycle.someManager.cache" cache.countLimit = 16 return cache }() func addTask(a: Int) { queue.addOperation { // " in" not needed? self.cache.setObject(a as AnyObject, forKey: a as AnyObject) print("hello \(a)") } } }
class ViewController: UIViewController { var someM: SomeManager? = SomeManager() override func viewDidLoad() { super.viewDidLoad() someM?.addTask(a: 1) someM?.addTask(a: 2) } // This connects to a button. @IBAction func invalidate() { someM = nil // Perfectly fine here. No leak. } }
Non vedo perché l’aggiunta di un’operazione non causerebbe un ciclo di conservazione: ‘SomeManager’ possiede fortemente la ‘coda’, che a sua volta possiede fortemente le chiusure aggiunte. Ogni chiusura aggiunta rimanda fortemente a ‘SomeManager’. Questo dovrebbe teoricamente creare un ciclo di conservazione che porta a perdite di memoria. Eppure Instruments dimostra che tutto è perfettamente a posto.
Nessuna perdita di immagine
Perché è questo il caso? In alcune altre API multi-threaded basate su blocchi, come “DispatchSource”, sembra che tu abbia bisogno dell’elenco di acquisizione. Vedi il codice di esempio di Apple `ShapeEdit ad esempio, in `ThumbnailCache.Swift`:
fileprivate var flushSource: DispatchSource ... flushSource.setEventHandler { in // Here guard let strongSelf = self else { return } strongSelf.delegate?.thumbnailCache(strongSelf, didLoadThumbnailsForURLs: strongSelf.URLsNeedingReload) strongSelf.URLsNeedingReload.removeAll() }
Ma nello stesso file di codice, `OperationQueue` non ha bisogno dell’elenco di cattura, pur avendo la stessa semantica: è un chiusura con riferimento al `sé` essere eseguita in modo asincrono:
fileprivate let workerQueue: OperationQueue { ... } ... self.workerQueue.addOperation { if let thumbnail = self.loadThumbnailFromDiskForURL(URL) { ... self.cache.setObject(scaledThumbnail!, forKey: documentIdentifier as AnyObject) } }
ho letto su Swift cattura dell’elenco di cui sopra, nonché le relative risposte COSÌ (citato nel post originale COSÌ), ma io ancora non so perché ` o ` non sono necessari in `OperationQueue` API, mentre sono in “in Spedizione” API. Non sono nemmeno sicuro di come non si trovino perdite nel caso “OperationQueue”.
Qualsiasi chiarimento sarebbe molto apprezzato.
Articoli recenti
- Processo di finitura in caduta
- Ultralight pesca a mosca
- Petrologia
- Transizione dalla bottiglia alla tazza
- DotLocal.org
- La” speed bump”, la posizione ideale per raggiungere il punto G
- Strepsiptera
- Biblioteche Universitarie
- TOP2A Amplificazione e sovraespressione nei tessuti del carcinoma epatocellulare
- Perché dovresti dire “Grazie” invece di” Scusa ” Quando fai qualcosa di sbagliato
Lascia un commento