'OSSpinLock' устарел в iOS 10.0: вместо этого используйте os_unfair_lock() из <os/lock.h>
Я ответил на этот вопрос, но предоставленное решение не сработало. Может кто-нибудь объяснить любой альтернативный подход или правильную реализацию с использованием os_unfair_lock()?
когда я использую OS_UNFAIR_LOCK_INIT, он кажется недоступным.
Благодарность!
2 ответа
Ты можешь использовать os_unfair_lock
как показано ниже,
var unfairLock = os_unfair_lock_s()
os_unfair_lock_lock(&unfairLock)
os_unfair_lock_unlock(&unfairLock)
В нас предупреждают, что мы не можем использовать напрямую в Swift, потому что «Swift предполагает, что все, что есть, может быть перемещено, а это не работает с мьютексом или блокировкой».
В этом видео спикер предлагает, чтобы, если вы должны использовать , вы поместили это в класс Objective-C (который не будет перемещать ). Или, если вы посмотрите на код stdlib , вы увидите, что вы можете оставаться в Swift, но использовать
UnsafeMutablePointer
вместо
struct
напрямую. (Спасибо bscothern за подтверждение этой закономерности .)
Так, например, вы можете написать
UnfairLock
класс, который позволяет избежать этой проблемы:
final class UnfairLock: NSLocking {
private let unfairLock: UnsafeMutablePointer<os_unfair_lock> = {
let pointer = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
pointer.initialize(to: os_unfair_lock())
return pointer
}()
deinit {
unfairLock.deinitialize(count: 1)
unfairLock.deallocate()
}
func lock() {
os_unfair_lock_lock(unfairLock)
}
func tryLock() -> Bool {
os_unfair_lock_trylock(unfairLock)
}
func unlock() {
os_unfair_lock_unlock(unfairLock)
}
}
Затем вы можете делать такие вещи, как:
let lock = UnfairLock()
А затем используйте
lock
а также
unlock
как вы бы с
NSLock
, но используя более эффективные за кулисами:
lock.lock()
// critical section here
lock.unlock()
И поскольку это соответствует
NSLocking
, вы можете использовать расширения, предназначенные для этого. Например, вот общий метод, который мы используем, чтобы гарантировать, что наши блокировки и разблокировки сбалансированы:
extension NSLocking {
func synchronized<T>(block: () throws -> T) rethrows -> T {
lock()
defer { unlock() }
return try block()
}
}
А также
lock.synchronized {
// critical section here
}
Но суть в том, что не используйте
os_unfair_lock
от Swift без чего-то вроде вышеперечисленного или того, что рассматривается в этом Concurrent Programming With GCD in Swift 3видео , оба из которых предоставляют стабильный адрес памяти для блокировки.