#Realmデータベース_Swift3.1 Carthageを使用して、ローカル内でマルチスレッドを使用する。([前回の記事->Swift3.1 Realmデータベースを使う] (http://qiita.com/daisukenagata/items/46bde08c8d5b384157b1))
こんにちは、iosフリーランスエンジニアの永田大祐と申します。
よろしくお願いします。
Github上に今回のサンプルがあります。Carthageバージョンがあります。
[Realm_Rx_Sample] (https://github.com/daisukenagata/Realm_Rx_Sample)
今回はこちらのサンプルソースにCarthageの導入方法、Swift3.1でマルチスレッドの書き方、挙動の紹介をさせていただきます。加えたコードに関しては、公開していませんので、実際に動かしたい場合は、記事のコードを書くか、コピペするか、で対応願います。
今回はCarthageの導入、マルチスレッドとは、書き方などを紹介させていただきます。
マルチスレッドは概念、方法など多様性がありますので、感覚で掴んだ後にアップルリファレンスなどを読むと、理解しやすいと思いました。
Swift3.1でのマルチスレッドの書き方の一部として記載します。
##アプリケーション機能説明
1.+ボタン商品名を入力できます。(数字を入力しないと、TableViewには表示されません。)
2.右上のReplyボタン 合計数字のクリア
3.検索バー (商品名左辺一文字のみ検索)
4.左上TextField数字入力TableViewに記載している100の数(TextField)
5.右上TextField掛け算、割り算の倍率設定左が1の場合は、反映されない
左が1より大きい数の場合に、左が掛け算、右が割り算になります。
6.左下Rxでの表記
7.右下Rxでの表記
8.タップ機能
左上TextFiledが空の場合は、TableViewのCellをタップごとにクリア
9.スワイプでcell毎に数値を削除
10.合計数値の表示
Rxの機能とRealmの機能をサンプルで実装してみました。
#Carthageの導入手順
gif動画などをよく使うので、Homebrewの導入方法でご案内します。
Homebrew-macOsパッケージマネージャー
###1.ターミナルで操作します。
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
###2.Carthageのinstallコマンド
brew install carthage
###3.プロジェクトのディレクトリへ移動
ターミナルにcdと書いて、ドラック&ドロップ,エンターでok
###4.Cartfileを作成(ターミナルで操作になります。)
vim Cartfile
###5.Cartfileへ記入(ターミナルで操作になります。)
####ターミナを選択して、escボタン 下記の内容を記入 shift+zでCartfile閉じます。
github "realm/realm-cocoa"
###6.Cartfileへ記入(ターミナルで操作になります。)
####iosのみ作成の場合。
carthage update --platform iOS
###7.Xcodeのプロジェクトにライブラリを追加
####結構間違いやすいので、動画も用意しました。
realmホームページにも導入手順の記載があります。
https://realm.io/jp/docs/swift/latest/
動画で矢印で示している部分が対応箇所になります。動画にあるrunscriptの記述があります。
対応箇所示す動画Youtube
XcodeのGeneral Linked Frameworks and Librariesから Realm.frameworkとRealmSwift.frameworkを導入対応箇所示す動画Youtube
###8.Xcodeの設定 BuildPhases(Run Script編)対応箇所示す動画Youtube
###9.Xcodeの設定 BuildPhases(Run Copy Files編)対応箇所示す動画Youtube
####シュミレータや実機で動かない場合にこの対応で、出来ました。
###10.Swift.fileに記述
####これでframeworkの導入は終了です!!!
#マルチスレッドとは
自分の感覚で捉えている内容ですが、、、
プログラム上の複数の電気の流れです。
高速で順番に電気の流れを切り替えながらプログラムを実行します。
###なぜマルチスレッドを使用するのか?
1.CPUの効率が向上します。
2.システムが安定して信頼性が増します。
3.CPUのパフォーマンスが向上します。
人間に置き換えると、、、
1.人間でも膨大に作業量があった場合でも、順番にTPOで作業を完結すると、混乱もしません。
2.作業の仕組みができれば、次から次へと実施できると思いませんか?
3.1.2.を繰り返すことにより経験ができ(キャッシュ的)よりよいコツや仕組みが構築されると思います。
###並列処理 非同期処理、直列処理 同期処理
直列処理 同期処理
タスクが実行中に他のタスクは、実行中のタスクを待ち、動作しない状態です。
一つづつ順番に処理をするのが、直列処理 同期処理。
並列処理,非同期処理
パラレルプロセッシング
複数のプロセッサに処理を分散して割り当て、同時に計算処理などを行う。(厳密には順番を作り実施している)iosではキューを生成する。GCDではディスパッチキュー。NSOperationではオペレーションキューを使う。自動的に適切な順番に(プログラムメソッド、タスク)を処理する。
非同期 Apex は、マルチスレッド。
非同期処理とは、ユーザが(プログラムメソッド、タスク)の終了まで待つことなく、(プログラムメソッド、タスク)をバックグラウンドでも実行するプロセスまたは機能です。
スレッドスケジュール管理がシステムの一部として組み込まれているので、複数の処理を同時に実施しても(厳密には順番で処理、)従来のスレッドよりも効率が向上します。
####具体例
GCD(Grand Central Dispatch)ディスパッチキュー
バックグラウンドスレッドの取得
public struct DispatchQoS : Equatableに各プロパティが用意されていて、.backgroundなどですね。こちらをすべてコンソールでログを確認しましたが、順番もランダムで明確な違いが、わかりません。こちらの用途別など、お判りな方がいらしたら,ご教授願います。
こちらをsafariから直にペーストするとAppleのリファレンスがあります。
apple-reference-documentation://hsF6fDaxOb
実際にXcodeで試しました。
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async {
//qosの「デフォルト値は'DispatchQoS.QoSClass.default`です
}
DispatchQueue.global().async {
//上記と同じ意味になります。
}
DispatchQueue.global(qos:.unspecified).async {
//グローバルキュー優先順位などは不明確です。
}
DispatchQueue.global(qos: .background).async {
//時間がかかる処理などのプログラム
}
//時間差でタスクを実施する。
let dispatchTime: DispatchTime = DispatchTime.now() + Double(Int64(2.0 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC
DispatchQueue.main.asyncAfter(deadline: dispatchTime, execute: {
})
###NSOperationQueueクラス
NSOperationは、KVOを利用して現在のオペレーションの状態を通知する仕組みを持っています。操作対象のセットの実行を調整します。キューに追加された後、それが明示的にキャンセルされるか、そのタスクの実行を完了するまで、操作はそのキューに残ります。キュー内の操作は(しかし、まだ実行していない)自体が優先レベルとの相互運用オブジェクトの依存関係に応じて編成され、それに応じて実行されます。アプリケーションは、これらの操作は、異なる動作キューに配置されている場合でも、操作のための絶対的な実行順序を提供する複数の操作のキューを作成し、操作の依存関係のいずれかに操作を提出することができます。操作対象は、その依存する操作のすべての実行が完了するまで実行する準備が考慮されていません。実行する準備ができている操作については、操作キューは、常に他の準備ができて操作への相対優先順位の高いものを実行します。
NSOperationオペレーションキュー
func operationQueue(_ op: Foundation.Operation) {
//時間がかかる処理などのプログラム
}
OperationQueue.main.addOperation {
//コールバックはメインスレッドで呼ばれない場合もある
}
###NSBlockOperationクラス
ブロックオブジェクトを並列実行するために、そのままの状態で使える クラスです。複数のブロックを実行できるので、ブロックオペレーションオブジェクトはグループとして振る舞います。すなわち、関係する ブロックすべての実行が完了した時点で、初めてオペレーションは完了したと見なします。
##直列処理 同期処理
順番で動く電気の流れ(プログラムメソッド、タスク)が動いている場合に、次の(プログラムメソッド、タスク)をロックして処理の順番を保証するような機構になっています。
CPUの性能よりも必ず順番を守るような場合はこちらで対応。
同期処理
(プログラムメソッド、タスク)を一時的に止めたり,再開したりする処理を(synchronization) という。データ通信のリクエストを出してからレスポンスが来るまで,ほかの処理を行わずにレスポンスを待ち続ける。
代表的な同期処理がセマフォ(semaphore)である.
セマフォは、カウンタであり、カウンタの数でタスクをストップしています。その際に、解放、カウンタのリセットなどを忘れるとデットロックに陥ります。
#URLSession,Semaphoreを実施例をGithubに上げました。
[SemaphoreSample]
(https://github.com/daisukenagata/SemaphoreSample/blob/master/semaphoreSample/ViewController.swift)
#Realmデータベースをマルチスレッドで使う場合は
Realm公式サイト日本語版ver2.6.2でもRealmデータベースは、マルチスレッド管理してくれているようです。(並行処理やマルチスレッドについて気にする必要はないようです。笑)*2017/06/10の現在では最新は2.8.0です。
####複数スレッド間でRealmを使う場合は
Realm公式サイト日本語版ver2.6.2 の複数スレッド間でRealmを使う場合というタイトルにサンプルが記載されていますので、参考になると思います。
#まとめ
今回はCarthageでTableView計算機をベースにCarthageの導入、マルチスレッドの概念、Swift3.1での書き方、挙動を紹介させていただきました。
実際に使う場合は、このような機能面を理解して設計段階から検討するのが通常と思いますので、もしこれからマルチスレッドを実際に動かし覚えたい方などは、参考になれば幸いです。
次回も実際に動くサンプルを用意して、RealmFileの肥大化による、最適化の対応手順など紹介させていただきます。
貴重な時間を割き、お読み下さいましてありがとうございました。😀