ruby風swift nsoperation編
TRANSCRIPT
HTTP GETして結果を表示する流れをNSOperationで非同期実行するコード private func getFirstPage() { items.removeAll(keepCapacity: false) indicator.startAnimating() let operation = NSBlockOperation(block: { if let searchResult = callSearchApi(self.keyword) { self.currentPage = searchResult.currentPage self.pageCount = searchResult.pageCount for item in searchResult.items { self.items.append(item) } } self.displaySearchResult() }) operationQueue.addOperation(operation) }
HTTP GETして結果を表示する流れをNSOperationで非同期実行するコード private func getFirstPage() { items.removeAll(keepCapacity: false) indicator.startAnimating() let operation = NSBlockOperation(block: { if let searchResult = callSearchApi(self.keyword) { self.currentPage = searchResult.currentPage self.pageCount = searchResult.pageCount for item in searchResult.items { self.items.append(item) } } self.displaySearchResult() }) operationQueue.addOperation(operation) }
NSBlockOperationを 普通に使うとこんな感じ
let operation = NSBlockOperation(block: { ... }) operationQueue.addOperation(operation)
( □の内側がブロック )
Swiftのシンタックスシュガー その1 ブロック引数は引数リストの 括弧の外に追い出せる
let operation = NSBlockOperation() { ... } operationQueue.addOperation(operation)
Swiftのシンタックスシュガー その2 他に引数がないときは括弧を省略できる
let operation = NSBlockOperation { ... } operationQueue.addOperation(operation)
operationを作ってqueueに入れる流れはパターン化している
let operation = NSBlockOperation { ... } operationQueue.addOperation(operation)
NSOperationQueueに addOperationの
ブロック渡しバージョンを追加したった
extension NSOperationQueue {
func addOperation(#block: ()->()) { let operation = NSBlockOperation { block() } self.addOperation(operation) } }
このコードが… private func getFirstPage() { items.removeAll(keepCapacity: false) indicator.startAnimating() let operation = NSBlockOperation(block: { if let searchResult = callSearchApi(self.keyword) { self.currentPage = searchResult.currentPage self.pageCount = searchResult.pageCount for item in searchResult.items { self.items.append(item) } } self.displaySearchResult() }) operationQueue.addOperation(operation) }
こんな風になって Ruby脳大満足
private func getFirstPage() { items.removeAll(keepCapacity: false) indicator.startAnimating() operationQueue.addOperation { if let searchResult = callSearchApi(self.keyword) { self.currentPage = searchResult.currentPage self.pageCount = searchResult.pageCount for item in searchResult.items { self.items.append(item) } } self.displaySearchResult() } }
(ついでに)ブロックの最後で呼んでいるdisplaySearchResultは結果をGUIに反映させ
るメソッドなんですが…
private func getFirstPage() { ... operationQueue.addOperation { ... self.displaySearchResult() } }
GUIを処理するoperationを mainQueueに放り込んでます
private func displaySearchResult() { NSOperationQueue.mainQueue().addOperation { self.tableView.reloadData() self.indicator.stopAnimating() } }