Cascable / runloop-queue

A GCD-like queue powered with the magic (and ruggedness) of CFRunLoop.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RunloopQueue

RunloopQueue is a class for running code on a background thread. It works a bit like Grand Central Dispatch, but is instead powered by the magic of run loops!

RunloopQueue works on both macOS and iOS.

queue = RunloopQueue(named: "My Cool Queue")

queue.async {
    // This code is running on a background thread.
    performAReallyLongOperation()
}

Usage

To use RunloopQueue, copy the RunloopQueue.swift file to your project. You can also add RunloopQueue+Streams.swift and RunloopQueue+URLConnection.swift if you'd like the Stream and URLConnection helpers.

Real-World Applications

RunloopQueue is currently being used in our Cascable family of apps, most notably in CascableCore, our SDK for working with WiFi-enabled cameras. CascableCore uses RunloopQueue for managing connections with the cameras it supports, and scheduling messages back and forth. You can find out more about CascableCore in our CascableCore Demo App.

RunloopQueue vs. Grand Central Dispatch

RunloopQueue is not designed to be a replacement for Grand Central Dispatch. In fact, if you're performing the common flow of starting on the main thread, performing some background work then calling back to the main thread at the end of the operation to update UI, you'll need Grand Central Dispatch to get back to the main thread.

queue.async {
    // This code is running on a background thread.
    performAReallyLongOperation()
    DispatchQueue.main.async {
        // This code is running on the main thread.
        performUIUpdates()
    }
}

However, RunloopQueue does offer some advantages over Grand Central Dispatch in certain circumstances:

Thread Consistency

RunloopQueue guarantees that all operations on a given RunloopQueue instance will be executed on the same thread, whether they're performed synchronously or asynchronously. This can be handy if you're interacting with a library that expects thread consistency.

Support For "Where Am I?" Checking

RunloopQueue provides the isRunningOnQueue() method for checking whether or not the code calling that method is running on the given RunloopQueue instance's thread.

Safe(er) Synchronous Operations

Grand Central Dispatch is very unsafe when it comes to synchronous operations, and it's very easy to deadlock your code. Personally, it's so unsafe that I ban its use in any project that I have that sort of influence over.

RunloopQueue, however, is much better in this regard. Thanks to the isRunningOnQueue() method, it can avoid deadlocks when synchronous operations start other synchronous operations:

queue.sync {
    queue.sync {
        print("Inner sync")
    }
    print("Outer sync")
}

Please note that as in any multithreaded environment, synchronous operations are prone to deadlocking if you're not careful.

Friendly to Streams and URL Connections

If you're working with streams or URLConnection objects, RunloopQueue provides convenience methods for enqueuing such objects on its background thread. This is great if you'd like to process your incoming data in the background:

let input: InputStream = 
let output: OutputStream = 

input.delegate = self
output.delegate = self

// Scheduling the streams on a RunloopQueue will cause their 
// delegate methods to be called on a background thread.
queue.schedule(input)
queue.schedule(output)

input.open()
output.open()

Objective-C

RunloopQueue is written in Swift 3, but is fully compatible with Objective-C.

self.runloopQueue = [[CBLRunloopQueue alloc] initWithName:@"My Cool Queue"];
[self.runloopQueue async:^{
    [self performAReallyLongOperation];
}];

[self.runloopQueue scheduleStream:self.inputStream];

License

For more information, see the LICENSE.md file.

About

A GCD-like queue powered with the magic (and ruggedness) of CFRunLoop.

License:BSD 3-Clause "New" or "Revised" License


Languages

Language:Swift 100.0%