82

GitHub - dreymonde/Delegated: ?‍♀️ Closure-based delegation without memory leaks

 6 years ago
source link: https://github.com/dreymonde/Delegated
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

README.md

Delegated

Swift Platform

Delegated is a super small package that solves the retain cycle problem when dealing with closure-based delegation.

Medium post here.

Usage

Before:

self.downloader = ImageDownloader()
downloader.didDownload = { [weak self] image in
    self?.currentImage = image
}

After:

self.downloader = ImageDownloader()
downloader.didDownload.delegate(to: self) { (self, image) in
    self.currentImage = image
}

No retain cycles! No memory leaks! No [weak self]! ?

Guide

Creating a delegated function

class NumberPrinter {
    var numberToString = Delegated<Int, String>()
}

Registering as a delegate

// somewhere inside init() or viewDidLoad() or similar
self.printer = NumberPrinter()
printer.numberToString.delegate(to: self) { (self, number) -> String in
    return self.convert(number: number)
}

By default, delegate(to:with:) will wrap self in a weak reference so that you don't need to remember to write [weak self] every time. This is the main feature of Delegated, but if this is not the behavior you want, you can use stronglyDelegated(to:with:) or manuallyDelegated(with:):

self.printer = NumberPrinter()
printer.numberToString.stronglyDelegate(to: self) { (self, number) -> String in
    // will hold a strong reference to  `self`
    return self.convert(number: number) 
}
let printer = NumberPrinter()
printer.numberToString.manuallyDelegate(with: { number in
    return String(number)
})

Calling a delegate

class NumberPrinter {
    
    var numberToString = Delegated<Int, String>()
    
    func printNumber(_ number: Int) {
        // .call returns nil if no delegate was set
        guard let string = numberToString.call(number) else {
            return
        }
        print(string)
    }
    
}

Removing a delegate

var numberToString = Delegated<Int, String>()
// ...
numberToString.removeDelegate()

Checking if delegate is set

var numberToString = Delegated<Int, String>()
// ...
numberToString.isDelegateSet // Bool

Installation

Delegated is available through Carthage. To install, just write into your Cartfile:

github "dreymonde/Delegated" ~> 0.1.0

Delegated is also available through Cocoapods:

pod 'Delegated', '~> 0.1.0'

And Swift Package Manager:

dependencies: [
    .Package(url: "https://github.com/dreymonde/Delegated.git", majorVersion: 0, minor: 1),
]

And, of course, you always have an option of just copying-and-pasting the code - Delegated is just one file, so feel free.

See also


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK