Skip to content

Instantly share code, notes, and snippets.

@kylehughes
Created May 16, 2025 23:50
Show Gist options
  • Save kylehughes/af88ae82f354cbc3d46ca6df6f1fd7ac to your computer and use it in GitHub Desktop.
Save kylehughes/af88ae82f354cbc3d46ca6df6f1fd7ac to your computer and use it in GitHub Desktop.
Example of using `weakify` to pass instance functions as one-liners without creating retain cycles.
@inlinable
public func weakify<Target, each Argument>(
_ closureProvider: @escaping (Target) -> (repeat each Argument) -> Void,
on target: Target
) -> (repeat each Argument) -> Void where Target: AnyObject {
{ [weak target] (arguments: repeat each Argument) in
guard let target else {
return
}
closureProvider(target)(repeat each arguments)
}
}
@inlinable
public func weakify<Target, Output, each Argument>(
_ closureProvider: @escaping (Target) -> (repeat each Argument) -> Output,
on target: Target,
default: @autoclosure @escaping () -> Output
) -> (repeat each Argument) -> Output where Target: AnyObject {
{ [weak target] (arguments: repeat each Argument) in
guard let target else {
return `default`()
}
return closureProvider(target)(repeat each arguments)
}
}
class MyView: UIView {
var onTap: ((String) -> Void)?
init() {
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MyViewController : UIViewController {
private lazy var myView: MyView = {
let view = MyView()
view.onTap = weakify(MyViewController.handleTap, on: self)
return view
}()
private func handleTap(id: String) {
print("id")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment