Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Weakly retaining an object in a closure without having to write [weak]
// I saw this trick in “Do you often forget [weak self], here is a solution”
import UIKit
class ViewController: UIViewController {
// move this variable inside viewDidLoad to see it being released
let downloader = Downloader()
override func viewDidLoad() {
let url = URL(string: "")!
// the compiler knows that 'object' will be an instance of 'downloader' without you passing self 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")
callback(delegate, data)
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
func countBytes(data: Data){
Copy link

janodev commented Apr 8, 2018

Of course, nothing prevents you from using it incorrectly: url, delegate: downloader) { [weak self] foobar, data in
    self?.downloader.countBytes(data: data)

Still, the closure parameter is a reminder not to use [weak self] so I’d say this is a useful idiom.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment