Eki是一个框架,用于轻松管理应用程序中的并发,它封装了功能强大的API Grand Central Dispatch。
内部GCD管理一个线程池,该线程池处理派遣队列并调用提交给它们的块。
主队列
UserInteractive
UserInitiated
默认
Utility
Background
队列按照优先级降序排列。
您可以通过以下方式访问它们
Queue.Background
您可以使用async
异步或使用sync
同步来在队列上派遣块
// Asynchronously
Queue.Utility.async {
...
}
// Or asynchronously using the operator shortcut
Queue.Utility <<< {
...
}
// Synchronously
Queue.Utility.sync { // Eki will prevent deadlock if you submit a sync on the current queue
...
}
您可以向队列发送多个块
Queue.Utility <<< {
// Block 1
} <<< {
// Block 2
}
// Or by submitting an array of blocks:
let blocks = [{
// Block 1
}, {
// Block 2
}]
Queue.Utility.async(blocks)
创建您自己的队列(串行或并发)
let queue = Queue(name:"QueueName", kind:.Concurrent)
queue.async{
...
}
使用屏障异步派遣块
let queue:Queue = Queue(name:"QueueName", type:.Concurrent)
...
queue |<| { // Or barrierAsync { }
// This block will be executed on the queue only after all previous submitted blocks have been executed
} <<< {
// This block will be executed only after the previous barrier block have completed
}
Queue.Background.after(2) {
// Do some stuff on Background after 2 seconds
}
Queue.Background.iterate(4) { i in
// Do some stuff on Background 4 times
}
Queue.current // Get current queue
Queue.Background.isCurrent // Check if background is current queue
请注意,这将仅在由设计初始化器 Queue(name:String, kind:Queue.Custom.Kind)
创建的 自定义队列、主队列 和 全局队列 上工作。
任务表示要在队列上派遣的块。
let t = Task(queue:.Utility) {
...
}
// Or
let t = Queue.Utility + {
...
}
t.async() // Dispatch asynchronously
group.async(t) // Dispatch on a group
let tasks:[Task] = ...
g.async(tasks) // Tasks dispatched on a group.
任务可以用 block
或另一个 Task
连接
t.chain {
// Executed after t on same queue
}.chain(Task(queue:.Main) {
// Executed after previous block on the main queue
})
t.async()
// Or chain directly after async and use the operator shortcut
t.async() <> {
// Executed after t on same queue
} <> Queue.Main + {
// Executed after previous block on the main queue
}
组允许将多个将被异步派遣的块相关联。
let g = Group(queue:.Utility) // By default the group queue is Background
g.async {
// Block dispatched on the group's queue.
} <<< {
// Block dispatched on the group's queue using the operator.
} <<< Task(queue:.Main) {
// Block dispatched on the Main queue (see Task).
}
let blocks:[()-> Void] = ...
g.async(blocks) // Blocks dispatched on the group's queue.
有两种方式来跟踪组块的执行
g.notify {
// Block executed on the group queue when blocks previously dispatched on the group have been executed.
}
g.notify(Queue.Main + {
// Block executed on the Main queue when blocks previously dispatched on the group have been executed.
})
g.wait() // Wait on the current process the group's blocks execution.
执行一次并只执行一次
let once = OnceDispatcher() // Store it somewhere
...
once {
// Executed only one time
}
定时器允许以一定的间隔或在指定日期安排一个队列中的块。
let timer = Timer.scheduleWithInterval(2, onQueue: .Background) {
// Do some stuff on Background after 2 seconds
}
// Equivalent to:
let timer = Timer(queue: .Background, interval: 2)
timer.handler {
// Do some stuff on Background after 2 seconds
}
timer.start() // Timers are paused at Initialization
定时器可以暂停或停止。
timer.pause()
timer.start()
timer.stop()
定时器可以重复,使用日期...
let date: NSDate = ...
let timer = Timer(queue: .Background, date: date)
timer.repeatInterval = 4
timer.tolerance = 1 // Add some tolerance
timer.handler {
// Do some stuff on Background on specified date and after every 4 seconds approximately
}
timer.start()
有三种类型的信号量
类型 | 初始资源 |
---|---|
二进制 | 1 |
屏障 | 0 |
计数(资源: UInt16) | 自定义 |
初始化信号量
let sem = Semaphore(.Binary)
let customSem = Semaphore(resource:5)
您可以使用 wait/signal
方法递减/递增信号量的资源。
sem.wait()
// Do some stuff when a resource is available
sem.signal()
// Or
sem--
...
sem++
或使用带有闭包的方便的 perform
方法。
sem.perform {
// Do some stuff when a resource is available
}
// Or
sem <<< {
...
}
互斥锁本质上与二进制信号量相同,只是锁定资源的块应该解锁资源。
let m = Mutex()
...
m.sync {
// Do some stuff when a mutext is available
}
// Or
m <<< {
...
}
LockedObject
是一个方便的类,可以使用内部 互斥锁 锁定对对象的访问。
let myobj = MyObject()
let l = LockedObject(myobj)
...
l.access { obj in
// Only one process at a time will access the locked object
}
// Or
l <<< { obj in
...
}