Created
April 8, 2018 13:51
-
-
Save janodev/01e8811186534deebc66902e83318d82 to your computer and use it in GitHub Desktop.
Weakly retaining an object in a closure without having to write [weak]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// I saw this trick in “Do you often forget [weak self], here is a solution” | |
// https://medium.com/anysuggestion/preventing-memory-leaks-with-swift-compile-time-safety-49b845df4dc6 | |
import UIKit | |
class ViewController: UIViewController { | |
// move this variable inside viewDidLoad to see it being released | |
let downloader = Downloader() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let url = URL(string: "https://baconmockup.com/300/200/")! | |
// the compiler knows that 'object' will be an instance of 'downloader' without you passing self | |
downloader.download(url: url, delegate: downloader) { object, data in | |
object.countBytes(data: data) | |
} | |
} | |
} | |
class Downloader | |
{ | |
/** | |
Download a URL. | |
- Parameter: delegate Passed to the closure. | |
- Parameter: Invoked when the object is downloaded. The delegate is already weakly held. You don’t need to use [weak] at the call site. | |
*/ | |
func download<Delegate: AnyObject>(url: URL, delegate: Delegate, with callback: @escaping (Delegate, Data) -> Void){ | |
let weakCallback: ((Data)->()) = { [weak delegate] data in | |
guard let delegate = delegate else { | |
print("the delegate is gone") | |
return | |
} | |
callback(delegate, data) | |
} | |
URLSession.shared.dataTask(with: url) { (data, response, error) in | |
guard let data = data else { return } | |
weakCallback(data) | |
}.resume() | |
} | |
func countBytes(data: Data){ | |
print(data) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Of course, nothing prevents you from using it incorrectly:
Still, the closure parameter is a reminder not to use
[weak self]
so I’d say this is a useful idiom.