読者です 読者をやめる 読者になる 読者になる

Rodhos Soft

備忘録を兼ねた技術的なメモです。

FutureパターンをSwiftで書く

Swiftで

まずリクエストプロトコルを作る。

public protocol Request {
    func getResult()->String    
}

それを実装するFurureを作る。

public class Future:Request {
    private let semaphore:DispatchSemaphore = DispatchSemaphore(value: 0)
    private var ready = false
    private var result:Result? = nil
    
    public func setResult(result:Result) {
        if ready {
            return
        }
        
        self.result = result
        self.ready = true
        
        semaphore.signal()
    }
    
    public func getResult() -> String {
        objc_sync_enter(self)
        
        while !ready {
            objc_sync_exit(self)
            semaphore.wait()
            objc_sync_enter(self)
        }
        
        objc_sync_exit(self)
        
        return self.result!.getResult()
        
    }
}

つまり、getResultすると結果がsetResultされるまで待たされるという動きになる。

Resultは即に返答する。

public class Result : Request {
    private var content:String
    
    public init(_ command:Int) {
        print("request start \(command)")
        Thread.sleep(forTimeInterval: 1.0)
        content = "result = \(command)"
        print("request end \(command)")
    }
    
    public func getResult() -> String {
        return content
    }
    
}


リクエストを受けつたマネージャはまずFurureを返し、
遅延して受け取る結果をsetResultで入れる。

public class RequestManager {
    public func request(command:Int) -> Future {
        
        let future = Future()
        
        DispatchQueue.global().async {
            let result = Result(command)
            future.setResult(result:result)
        }
        
        return future
    }
}

ソースコードは以下に
github.com