ruby風swift nsoperation編

21
Ruby風Swift NSOperation編 藤本尚邦 2014年11月15日

Upload: hisakuni-fujimoto

Post on 29-Jul-2015

451 views

Category:

Software


0 download

TRANSCRIPT

Ruby風Swift NSOperation編

藤本尚邦 2014年11月15日

Swiftの関数呼び出しで引数に ブロックを渡すときの

シンタックスシュガーが自由すぎるせいで Ruby風に書きたくなる病、通称

Ruby脳 に冒されそうです

作ってるアプリの簡単な紹介

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)

この構文を考えた人や 採用に賛成した人は多分

Ruby脳

operationを作ってqueueに入れる流れはパターン化している

let operation = NSBlockOperation { ... } operationQueue.addOperation(operation)

これをRuby脳で 眺めていると

let operation = NSBlockOperation { ... } operationQueue.addOperation(operation)

operationQueue.addOperation { ... }

addOperationに直接ブロックを渡せればいいじゃん

operationQueue.addOperation { ... }

となります

そこでextension登場

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() } }

あなたもRuby脳になってみませんか?

以上です どうもありがとう ございました