Swift 책을 검색했지만 @synchronized의 Swift 버전을 찾을 수 없습니다. Swift에서 상호 배제를 어떻게합니까?
답변
GCD를 사용할 수 있습니다. 보다 약간 장황 @synchronized
하지만 대체 기능으로 작동합니다.
let serialQueue = DispatchQueue(label: "com.test.mySerialQueue")
serialQueue.sync {
// code
}
답변
나는 이것을 직접 찾고 있었고 아직 이것에 대한 신속한 내부에 네이티브 구성이 없다는 결론에 도달했습니다.
Matt Bridges 및 다른 코드에서 본 코드 중 일부를 기반 으로이 작은 도우미 기능을 구성했습니다.
func synced(_ lock: Any, closure: () -> ()) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
사용법은 매우 간단합니다
synced(self) {
println("This is a synchronized closure")
}
내가 찾은 문제가 하나 있습니다. 잠금 인수로 배열을 전달하면이 시점에서 매우 혼란스러운 컴파일러 오류가 발생하는 것으로 보입니다. 그렇지 않으면 원하는대로 작동하는 것 같습니다.
Bitcast requires both operands to be pointer or neither
%26 = bitcast i64 %25 to %objc_object*, !dbg !378
LLVM ERROR: Broken function found, compilation aborted!
답변
나는 여기에 많은 답변을 좋아하고 사용하므로 가장 적합한 것을 선택하십시오. 즉, objective-c와 같은 것이 필요할 때 선호하는 방법 은 신속한 2에 도입 된 진술을 @synchronized
사용합니다 defer
.
{
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
//
// code of critical section goes here
//
} // <-- lock released when this block is exited
이 방법에 대한 좋은 일이, 중요한 부분은 원하는 어떤 방식으로 포함하는 블록을 종료 할 수 있다는 것입니다 (예를 들어, return
, break
, continue
, throw
), 그리고 “를 연기 문 내의 문은 프로그램 제어가 전송되는 방식에 상관없이 실행됩니다.” 1
답변
objc_sync_enter(obj: AnyObject?)
와 사이에 문을 삽입 할 수 있습니다 objc_sync_exit(obj: AnyObject?)
. @synchronized 키워드는 표지 아래 해당 방법을 사용하고 있습니다. 즉
objc_sync_enter(self)
... synchronized code ...
objc_sync_exit(self)
답변
@synchronized
Objective-C 의 지시문 아날로그는 rethrows
Swift에서 임의의 반환 유형과 훌륭한 동작을 가질 수 있습니다 .
// Swift 3
func synchronized<T>(_ lock: AnyObject, _ body: () throws -> T) rethrows -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return try body()
}
의 사용 defer
문은 직접 임시 변수를 도입하지 않고 값을 반환 할 수 있습니다.
Swift 2에서 @noescape
더 많은 최적화를 허용하기 위해 속성을 클로저에 추가하십시오 .
// Swift 2
func synchronized<T>(lock: AnyObject, @noescape _ body: () throws -> T) rethrows -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return try body()
}
GNewc [1] (임의의 리턴 타입이 마음에 드는 곳)과 Tod Cunningham [2] (나는 좋아하는 곳 ) 의 답변을 바탕으로합니다 defer
.
답변
스위프트 4
Swift 4에서는 GCD 디스패치 큐를 사용하여 리소스를 잠글 수 있습니다.
class MyObject {
private var internalState: Int = 0
private let internalQueue: DispatchQueue = DispatchQueue(label:"LockingQueue") // Serial by default
var state: Int {
get {
return internalQueue.sync { internalState }
}
set (newState) {
internalQueue.sync { internalState = newState }
}
}
}
답변
반환 기능을 추가하려면 다음을 수행하십시오.
func synchronize<T>(lockObj: AnyObject!, closure: ()->T) -> T
{
objc_sync_enter(lockObj)
var retVal: T = closure()
objc_sync_exit(lockObj)
return retVal
}
이어서 다음을 사용하여 호출 할 수 있습니다.
func importantMethod(...) -> Bool {
return synchronize(self) {
if(feelLikeReturningTrue) { return true }
// do other things
if(feelLikeReturningTrueNow) { return true }
// more things
return whatIFeelLike ? true : false
}
}