Giter Club home page Giter Club logo

chary's Introduction

Chary

Chary is a DispatchQueue Utilities for safer sync and asynchronous programming. It helps to avoid a race condition when dealing with multithreaded application

Codacy Badge build test SwiftPM Compatible Version License Platform

Requirements

  • Swift 5.0 or higher (or 5.3 when using Swift Package Manager)
  • iOS 10.0 or higher
  • macOS 10.0 or higher
  • tvOS 10.10 or higher
  • watchOS 4 or higher

Installation

Cocoapods

Chary is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Chary'

Swift Package Manager from XCode

  • Add it using XCode menu File > Swift Package > Add Package Dependency
  • Add https://github.com/hainayanda/Chary.git as Swift Package URL
  • Set rules at version, with Up to Next Major option and put 1.0.7 as its version
  • Click next and wait

Swift Package Manager from Package.swift

Add as your target dependency in Package.swift

dependencies: [
  .package(url: "https://github.com/hainayanda/Chary.git", .upToNextMajor(from: "1.0.7"))
]

Use it in your target as Chary

 .target(
    name: "MyModule",
    dependencies: ["Chary"]
)

Author

Nayanda Haberty, [email protected]

License

Pharos is available under the MIT license. See the LICENSE file for more info.


Basic Usage

Two utilities come with Chary, Atomic propertyWrapper and DispatchQueue extensions

Atomic propertyWrapper

Atomic propertyWrapper is a propertyWrapper to wrap a property so it could be accessed and edited atomically:

class MyClass {
    @Atomic var atomicString: String = "atomicString"
    ...
    ...
}

then the atomicString will be Thread safe regardless of where it is accessed or edited.

DispatchQueue.main.async {
    myClass.atomicString = "from main thread"
}
DispatchQueue.global().async {
    myClass.atomicString = "from global thread"
}

DispatchQueue Extensions

Chary has some DispatchQueue Extension that will help when dealing with multithreaded.

Check current queue

You can check current DispatchQueue using isCurrentQueue(is:) which will check is the queue given is the current queue or not.

myQueue = DispatchQueue(label: "myQueue")
myQueue.sync {
    // this will print true
    print(DispatchQueue.isCurrentQueue(is: myQueue))
}
// this will print false
print(DispatchQueue.isCurrentQueue(is: myQueue))

What it did do is registering the DispatchQueue given for detection and compare the current detectable queues with the given one:

public static func isCurrentQueue(is queue: DispatchQueue) -> Bool {
    queue.registerDetection()
    return current == queue
}

Calling DispatchQueue.current will not guarantee to return the current DispatchQueue, since it can only return only DispatchQueue that already been registered for detection. There are some default DispatchQueue that will auto registered when current is called:

  • DispatchQueue.main
  • DispatchQueue.global()
  • DispatchQueue.global(qos: .background)
  • DispatchQueue.global(qos: .default)
  • DispatchQueue.global(qos: .unspecified)
  • DispatchQueue.global(qos: .userInitiated)
  • DispatchQueue.global(qos: .userInteractive)
  • DispatchQueue.global(qos: .utility)

Other than that, it will need manual call for registerDetection() to allow the DispatchQueue to be accesible by calling DispatchQueue.current. Since isCurrentQueue(is:) will automatically register the given DispatchQueue, the queue passed will be accesible from DispatchQueue.current after.

Safe Sync

Running sync from DispatchQueue sometimes can raise an exception if it is called in the same DispatchQueue. To avoid this, you can use safeSync instead which will check the current queue first and decide whether it needs to run the block right away or by using the default sync. You don't need to register the DispatchQueue since it will automatically register the DispatchQueue before checking:

DispatchQueue.main.safeSync {
    print("this will safely executed")
}

Async if needed

Sometimes you want to execute the operation right away if it's in the right DispatchQueue instead of running it asynchronously by using async. Like when you update UI, it's better if you run it right away instead of putting it in the asynchronous queue if you are already in DispatchQueue.main. You can use asyncIfNeeded to achieve that functionality right away. It will check the current DispatchQueue and decide whether it needs to run right away or by using the default async. You don't need to register the DispatchQueue since it will automatically register the DispatchQueue before checking:

DispatchQueue.main.asyncIfNeeded {
    print("this will executed right away or asynchronously if in different queue")
}

Contribute

You know-how. Just clone and do a pull request

chary's People

Contributors

hainayanda avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

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.