質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
並列処理

複数の計算が同時に実行される手法

バックグラウンド処理

バックグラウンド処理とは、マルチタスク環境において、ユーザーに対して前面に表示させている処理の裏側で実行させる処理のことを呼びます。バックグラウンド処理を行う事によって、ユーザーが他の作業に携わることが可能となります。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

2回答

7240閲覧

swift 非同期処理 メインスレッド、サブスレッドについての挙動

YutaMatsuura715

総合スコア2

並列処理

複数の計算が同時に実行される手法

バックグラウンド処理

バックグラウンド処理とは、マルチタスク環境において、ユーザーに対して前面に表示させている処理の裏側で実行させる処理のことを呼びます。バックグラウンド処理を行う事によって、ユーザーが他の作業に携わることが可能となります。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

3クリップ

投稿2021/06/15 02:52

swiftで非同期処理、マルチスレッドを学習しているのですが、概念というかいまいち仕組みについてピンときません。
私の考えがずれている可能性があるので間違っている箇所があればご指摘いただきたいです。

swiftで
①DispatchQueue.mian.async
②DispatchQueue.mian.sync
③DispatchQueue.global.async
④DispatchQueue.global.sync

①② と ③④の違いはメインスレッドで行うか、サブスレッドで行うかの違い。

① と ② の違いは並列で行うか直列で行うか

③ と ④ の違いも並列で行うか。直列で行うか。

とある本では通信に関する処理は自動でサブスレッドで非同期処理(並列)で行われると書いてありました。
UIに関する処理はメインスレッドで。

つまり、API通信や、Firebaseなどから情報を取得する際はサブスレッドで並列処理が自動で行われているということになります。

swift

1import UIKit 2class ViewController:UIViewController{ 3 var label:UITextView! 4 5 override func viewDidLoad(){ 6 super.viewDidLoad() 7 label=UITextView() 8 label.text="ロード中" 9 label.frame=CGRect(x:10,y:30,width:self.view.frame.width - 20,height:300) 10 self.view.addSubview(label) 11 12 let unit = "metric" 13 let appId = "ebaf2eeae4e09f63ccdcb4e59e5fac68" 14 let city = "Tokyo" 15 let urlString="https://api.openweathermap.org/data/2.5/weather?units=(unit)&APPID=(appId)&q=(city)" 16 let url=URL(string:urlString)! 17 var request=URLRequest(url:url) 18 request.httpMethod="GET" 19 20 let task = URLSession.shared.dataTask(with:request){(data,response,error) in 21 guard let data = data else{ return } 22 do { 23 let object = try JSONSerialization.jsonObject(with:data,options:[]) as? [String:Any] 24 print(object) 25          //①メインスレッドで非同期処理? 26 DispatchQueue.main.async{ 27 self.label.text = object?.description 28 self.label.sizeToFit() 29 } 30 } catch let e{ 31 print(e) 32 } 33 } 34 task.resume() 35 } 36 override func didReceiveMemoryWarning(){ 37 super.didReceiveMemoryWarning() 38 } 39}

ある本のソースコードです。天気のwebAPIへリクエストを送り、そのレスポンス(json)を表示するプログラムです。
データの取得時に①の処理がありますが、このロジックはどのように動いているのかが理解できません。
通信に関するものはサブスレッドで行われるらしいですが具体的にどこからどこまでがサブスレッドで行われているのか。
なぜ、メインスレッドに処理を渡すことでこのソースコードは応答性の向上が見込めるのか。
結局レスポンスが返ってきた瞬間にメインスレッドの並列の処理に即処理を渡すコードを書くことですぐに反映されるからってことでいいんですかね。メインスレッドは直列で他の処理を行ったりするから並列でUIの更新をする的な?

例えば、逆に

swift

1DispatchQueue.main.async{ 2 self.label.text = object?.description 3 self.label.sizeToFit() 4 }

の処理を外に放り出すとどのようなロジックで応答性に差が出るのでしょうか

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

sync, asyncは同期、非同期のことです。(synchronous, asynchronous)

直列、並列はserial, parallel、そして並行はconcurrentです。

GCD (Grand Central Dispatch)のDispatchQueueではserialとconcurrentが選択可能です。

DispatchQueueはスレッドとは別のもので、キューというデータ構造を持っており「動作」を登録することが出来ます。

serialなDispatchQueueはキューから1つ「動作」を取り出し実行し、その完了を確認してから次の「動作」を取り出し実行します。
concurrentなDispatchQueueは「動作」の完了を待たずに次の「動作」を実行させます。
これが直列と並行の違いです。
(並列と並行の違いはご自身が納得するものを探してください)

DispatchQueueへの動作の登録はsyncあるいはasyncメソッドを用いて行います。
syncメソッドは「動作」が完了するまでメソッドが終了しません。
syncメソッドが終了したときには「動作」も完了しています。

asyncメソッドは「動作」の登録のみを行い実行/完了を待たずにメソッドが終了します。
asyncメソッドが終了しても「動作」は完了していません。

これが同期と非同期の違いです。

投稿2021/06/15 08:22

MasakiHori

総合スコア3391

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YutaMatsuura715

2021/06/16 22:22 編集

回答ありがとうございました
guest

0

どこからどこまでがサブスレッドで

Swift

1override func viewDidLoad() { 2 // (A)メインスレッド 3 let task = URLSession.shared.dataTask(with:request){ 4 // (B)サブスレッド 5 DispatchQueue.main.async{ 6 // (C)メインスレッド 7 } 8 // (D)サブスレッド 9 } 10 // (E)メインスレッド 11}

 上記のようになります。
ただし、実行順番は(A)(B)(C)(D)(E)ではありません。

 最初に(A)の部分が実行されます。
その中で、URLSession.shared.dataTask関数が、{}内をサブスレッドに渡します。渡した時点でこの関数は終わるので、(E)の部分に実行が移ります。ちなみに、(A)と(E)は一連のメインスレッドです。

 URLSession.shared.dataTaskで{}内が渡されたサブスレッドは、メインスレッドとは関係なく(B)の処理を行います。(B)の中で、通信など時間がかかる処理を行います。その間、メインスレッドはこのサブスレッドと無関係に動けるので、画面の書き換え(ユーザーが画面をスクロールさせる等)を行うことができます。

 通信が終わった後、DispatchQueue.main.async関数が、{}内をメインスレッドに渡します。渡した時点でDispatchQueue.main.async関数は終わるので、(D)の部分に実行が移ります。(D)の部分を実行し終わると、このスレッドは処理が終わるので無くなります。

 DispatchQueue.main.asyncで{}内が渡されたメインスレッドは、(C)を実行します。

 一連の処理を並列処理を使わずに書いたとすると、viewDidLoadが呼ばれてから通信が終わるまで、画面には何も表示されない、または、表示されてもユーザーは何も操作できなくなります。これは、画面表示やユーザーアクセスがメインスレッドで行われているためです。

投稿2021/06/15 04:17

AOKINAO

総合スコア268

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問