Warum wird [weak self] oder [unowned self] in der Operationswarteschlange nicht benötigt?
On Oktober 5, 2021 by adminDies ist eine Swift-Capture-Liste und wie es verwendet werden kann, um Retain-Zyklus zu vermeiden, kann ich nicht helfen, etwas Rätselhaftes über OperationQueue zu bemerken: Es braucht weder `oder `, um Speicherverlust zu verhindern.
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. } }
Ich sehe nicht, warum das Hinzufügen einer Operation keinen Beibehaltungszyklus verursachen würde: `SomeManager‘ besitzt stark die ‚queue‘, die wiederum stark die hinzugefügten Closures besitzt. Jeder hinzugefügte Verschluss bezieht sich stark auf `SomeManager`. Dies sollte theoretisch einen Retain-Zyklus erzeugen, der zu einem Speicherverlust führt. Dennoch zeigt es, dass alles vollkommen in Ordnung ist.
Kein Leck Bild
Warum ist das so? In einigen anderen Multithread-, blockbasierten APIs wie ‚DispatchSource‘ scheinen Sie die Erfassungsliste zu benötigen. Siehe Apples Beispielcode ‚ShapeEdit zum Beispiel in ‚ThumbnailCache .rasch`:
fileprivate var flushSource: DispatchSource ... flushSource.setEventHandler { in // Here guard let strongSelf = self else { return } strongSelf.delegate?.thumbnailCache(strongSelf, didLoadThumbnailsForURLs: strongSelf.URLsNeedingReload) strongSelf.URLsNeedingReload.removeAll() }
In derselben Codedatei benötigt `OperationQueue` die Erfassungsliste jedoch nicht, obwohl sie dieselbe Semantik aufweist: Sie übergeben einen Abschluss mit Verweis auf `self`, der asynchron ausgeführt werden soll:
fileprivate let workerQueue: OperationQueue { ... } ... self.workerQueue.addOperation { if let thumbnail = self.loadThumbnailFromDiskForURL(URL) { ... self.cache.setObject(scaledThumbnail!, forKey: documentIdentifier as AnyObject) } }
Ich habe über die oben erwähnte Erfassungsliste von Swift sowie verwandte SO-Antworten gelesen (die im ursprünglichen Beitrag zu SO erwähnt wurden), weiß aber immer noch nicht, warum `oder` in der API „OperationQueue“ nicht benötigt werden, während sie sich in der API „Dispatch“ befinden. Ich bin mir auch nicht sicher, wie im Fall `OperationQueue` keine Lecks gefunden werden.
Jede Klarstellung wäre sehr dankbar.
Neueste Beiträge
- Tumble Finishing Prozess
- Ultraleichtes Fliegenfischen
- Petrologie
- Übergang von der Flasche zur Tasse
- DotLocal.org
- Der „Speed Bump“, die ideale Position, um den G-Punkt zu erreichen
- Strepsiptera
- Universitätsbibliotheken
- TOP2A-Amplifikation und -überexpression in hepatozellulären Karzinomgeweben
- Warum Sie „Danke“ anstelle von „Entschuldigung“ sagen sollten, wenn Sie etwas falsch machen
Schreibe einen Kommentar