readme.md 2.74 KB
Newer Older
Aral Balkan's avatar
Aral Balkan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
# Delay


Delay is an easy-to-use micro-library for delaying code execution in a cancellable manner. It uses Grand Central Dispatch and blocks.

## Usage

Delay has three main use cases:

  * Delay execution of a block to the next stack frame (next frame of the runloop)
  * Delay execution by N seconds
  * Delay execution in a cancellable manner

### Execute on next stack frame

	delay(0.0)
	{
	  // Do something.
	}

### Execute after an arbitrary number of seconds

	delay(42.0)
	{
	  // Do something.
	}

### Cancel before execution

	let cancellableBlock = delay(42.0)
	{
	  // Do something.
	}

	cancellableBlock.cancel()

### Idiom: throttle user input

	var cancellableCommand:CancellableDelayedCommand?

	// …

	// Throttle expensive operation so it is performed at
	// most every second, no matter how often a signal is received.
    cancellableCommand = cancellableCommand?.reset() ?? delay(1.0)
    {
        // Perform expensive operation:
        // …
    }

For example, you can use this to implement auto-complete without flooding the lookup method on every keystroke.

	var textDidChangeHandler:NotificationHandler?
	var cancellableAutoCompleteCommand:CancellableDelayedCommand?

	// …

	override func viewWillAppear()
	{
		textDidChangeHandler = handle(NSControlTextDidChangeNotification, from: myTextInput)
	    {
	        /* with */ notification in
	        
	        let text = self.myTextInput.stringValue
	        
	        // Throttle auto-complete lookups to every 1/3rd of a second.
	        cancellableAutoCompleteCommand = cancellableAutoCompleteCommand?.reset() ?? delay(0.3)
	        {
	            // Perform expensive operation: look-up text for auto-complete
	            // …
	        }
	    }	
	}

	override func viewWillDisappear()
	{
		cancellableAutoCompleteCommand.cancel()
		textDidChangeHandler.remove()
	}

Read more about the library [in this blog post](https://ind.ie/labs/blog/delay) on [Ind.ie Labs](https://ind.ie/labs).

## On performance

Note that Delay is optimised for ease of authoring, beauty of interface and clarity of intent. I haven’t run into performance issues and hence haven’t felt the need to run any benchmarks at the moment but [Evgenii Rtishchev’s purely-block-based CancelBlocks](https://github.com/katleta3000/CancelBlocks/blob/master/CancelBlocks.swift), on which my solution is based, is a lighter alternative should you need it.

## Credits

Delay based on the work of [Evgenii Rtishchev](https://github.com/katleta3000/CancelBlocks) and [Chris Brind](http://stackoverflow.com/questions/24034544/dispatch-after-gcd-in-swift/24318861#24318861) (with thanks to [Cezary Wojcik](http://stackoverflow.com/a/24034838/253485).)

Copyright © Aral Balkan. 
Released with ♥ by [Ind.ie](https://ind.ie) under the MIT License.