Coder Social home page Coder Social logo

ward's Introduction

Ward

Travis CI code cov release Swift 4.1 license

CocoaPods compatible Carthage compatible SwiftPM compatible platforms

ward is a Swift micro-framework to help with cleaning up ugly memory management syntax.

Before

func useAClosureBasedAPI(block: @escaping (Something) -> Void) { ... }

useAClosureBasedAPI(block: { [weak self] something in
    guard let strongSelf = self else {
        return
    }

    strongSelf.handle(something)
})

After

useAClosureBasedAPI(block: ward(self) { strongSelf, something in
    strongSelf.handle(something)
})

Under the hood

public func ward<Object: AnyObject>(_ object: Object, f: @escaping (Object) -> Void) -> () -> Void {
    return { [weak object] in
        guard let object = object else { return }
        f(object)
    }
}

Other use cases

Supports Swift's unapplied method references

Use the curried function API to call Swift's automatically synthesized static accessors for instance methods:

class MyViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        useAClosureBasedAPI(block: ward(self, MyViewController.handleSomething))
        // MyViewController.handleSomething is of type (MyViewController) -> (Something) -> Void
    }

    func handleSomething(_ something: Something) {
        ...
    }
}

Supports non-Void returning closures

/// Returns half of `count` while `self` is alive. If `self` has deallocated, returns the provided default value (nil).
let halfOfCountIfSelfAlive: (_ count: Int) -> Int? = ward(self, else: nil) { _, count in
    return count / 2
}

Supports ward for multiple objects

let anObject = MyClass()
ward(self, anObject) { strongSelf, theObject in
   ...
}

Try it out!

Carthage

github 'OneAfternoon/Ward' ~> 1.0

CocoaPods

pod 'Ward', '~> 1.0'

Swift Package Manager

.package(url: "https://github.com/OneAfternoon/Ward.git", from: "1.0.0")

Authors

ward's People

Contributors

lazyvar avatar swain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

bluepick

ward's Issues

More descriptive syntax around ward(_:)

I'd argue that the current syntax of ward(_:) doesn't correctly communicate it's functionality.

Merriam-Webster Definition of ward:

ward
v: the action or process of guarding

In our current syntax, it's looks like we are guarding, or protecting the object passed in:

ward(self) { strongSelf in // Reads as "protect self"
    ...
}

This could potentially lead the reader to believe that self is going to be "protected" in some way (potentially "kept alive").

In reality, what we're really doing is are guarding/protecting the function from the scenario where self (or whatever object) has become nil.

However, instead of trying to refer to this abstract "scenario", we can just thing of the object being passed in as "dangerous". We're protecting a function from a "dangerous" object, which could become nil at any moment.

So...

Proposed new syntax

Using against.

ward(against: self) { strongSelf
    ...
}

Advantages

  1. This syntax more effectively communicates that the object being protected is the function, not the reference type being passed in.

  2. This syntax remains communicative across all of ward's functions:

Warding against multiple references, AND using generic input and output values

let first = MyClass()
let second = MyClass()

let isEvenAndObjectsAlive: (Int) -> Bool = ward(against: first, second, else: false) { _, _, integer in
    return integer % 2 == 0
}

Disadvantages

  1. This syntax is more verbose than the current syntax, and causes some clogging when working with multiple "warded" references and/or generic outputs. This is an important disadvantage, given that simplicity is a top priority for the framework.

  2. The current approach is working software, and this change is API-breaking. One might say, "don't fix it if it ain't broke".

Open to thoughts, suggestions, criticism, and anything else you can throw at me!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.