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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Swift

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

Q&A

解決済

2回答

576閲覧

viewDidLoadで呼ばれているメソッドより早く実行されるextension内のメソッドについて

momokoko

総合スコア38

Swift

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

0グッド

0クリップ

投稿2021/02/02 14:37

ビルドするとコンソールは
viewDidLoad①

viewDidLoad②

collectionViewメソッド

fetchUserメソッド
の順番で呼ばれております。

質問が2点あります。

①なぜcollectionViewメソッドがfetchUserメソッドがより早く呼ばれるのか。

②collectionViewメソッドはどこから呼び出されているのか。

①について自分の考え
viewDidLoad内でfetchUserメソッドが呼ばれているためfetchUserメソッドの実行の方がより早いと思ってしまう。

よろしくお願い致します。

import UIKit private let cellIdentifier = "ProfileCell" private let headerIdentifier = "ProfileHeader" class ProfileController: UICollectionViewController { // MARK: - Properties var user: User? { didSet { collectionView.reloadData(); print("userプロパティ")} } // MARK: - Lifecyzcle override func viewDidLoad() { super.viewDidLoad() print("viewDidLoad①") configureCollectionView() fetchUser() print("viewDidLoad②") } // MARK: - API func fetchUser() { UserService.fetchUser { (user) in --------------------------------------------------------- print("fetchUserメソッド") --------------------------------------------------------- self.user = user self.navigationItem.title = user.username } } // MARK: - Helpers func configureCollectionView() { collectionView.backgroundColor = .white collectionView.register(ProfileCell.self, forCellWithReuseIdentifier: cellIdentifier) collectionView.register(ProfileHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerIdentifier) } } // データソース // MARK: - UICollectionViewDataSource extension ProfileController { override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { --------------------------------------------------------- print("collectionViewメソッド") --------------------------------------------------------- return 9 } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! ProfileCell return cell } //ヘッダー override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerIdentifier, for: indexPath) as! ProfileHeader if let user = user { header.viewModel = ProfileHeaderViewModel(user: user) } else { print("ユーザーがまだいません") } return header } }

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

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

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

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

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

hoshi-takanori

2021/02/02 18:19 編集

fetchUser の中身を 2 つに分けて考える必要があります。一つは UserService.fetchUser(completion:) の呼び出し、もう一つはそれに対する引数であるクロージャ { (user) in 〜 }。fetchUser が呼ばれると、UserService.fetchUser(completion:) が実行されてユーザーの情報の取得が開始されますが、おそらくネットワーク通信が絡んで実際に情報が取得されるまでには時間がかかります。が、UserService.fetchUser(completion:) は情報の取得を待たずにいったん終了して、情報が取得された後にクロージャ { (user) in 〜 } の中身が実行されます。このため、print("fetchUserメソッド") の表示が最後となります。
TsukubaDepot

2021/02/03 07:11

hoshi-takanoriさん、 ここに書かれているコメントは、ズバり回答そのものですから、回答本文に書かれたほうが良いと思います。 「質問への追記」に書かれたコメントは意外と読まない回答者が多いため、せっかく適切なコメントをされても見られない可能性が高いと思います(で、実際間違った回答がついてしまいました)。
momokoko

2021/02/03 14:22

hoshi-takanoriさん、ありがとうございます。 https://teratail.com/questions/320084 こちらの質問の(2)と繋がっていて、双方とも理解が進みました。 大変恐縮ですが、hoshi-takanoriさんの回答を転記して自己解決として転記させて頂きます。 次回から回答いただける際は、「回答」でいただけると自己解決とする心苦しさがないです!笑 TsukubaDepotさん、コメントありがとうございます。
TsukubaDepot

2021/02/03 14:28

いや、自己解決でもいいと思いますよ。 たぶん、hoshi-takanoriさんは自己解決を案に促しているのだと思います。 質問がオープン(未解決)のまま残されるよりも、「具体的に何がわかったのか」記載して自己解決される方が何倍も有益だと思います。
momokoko

2021/02/03 15:36 編集

たしかにそうかもしれないですね。 この質問で自己解決を書いているときに新しい気付きや疑問が生まれました。 ・なぜ結果取得を待たずして一旦fetchUser()は終了するのか です。 また整理して、理解できなかったら別途質問を開きます。 以下はコメント上の質問になってしまい恐縮なんですが、 ②collectionViewメソッドはどこから呼び出されているのか。 はどこになるのでしょうか。
TsukubaDepot

2021/02/03 15:51

>以下はコメント上の質問になってしまい恐縮なんですが、 >②collectionViewメソッドはどこから呼び出されているのか。 下記の回答にコメントしましたので、そちらをご参照ください。
guest

回答2

0

自己解決

前提
・fetchUserメソッドは、2つの処理がある。

------①--UserService.fetchUser------- ------②----- { (user) in print("fetchUserメソッド") self.user = user self.navigationItem.title = user.username }-------②------ }

(1)UserService構造体内のfetchUserメソッドを取得を呼び出す処理: ①

(2)(1)の結果の取得後の処理: ②

回答の答え
・viewDidLoad()内で呼ばれるfetchUser()では(1)の処理を行っている。
・結果取得を待たずして一旦fetchUser()は終了するため、print("fetchUserメソッド")が出力されず、後続処理のcollectionViewメソッドが先に呼ばれるように見えている。

投稿2021/02/03 15:25

編集2021/02/03 15:28
momokoko

総合スコア38

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

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

TsukubaDepot

2021/02/03 15:50

> ②collectionViewメソッドはどこから呼び出されているのか。 https://medium.com/@shiba1014/viewcontroller%E3%81%AE%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB-37151427bda5 上記のページに、ViewController のライフサイクル(インスタンス化されてからUIパーツが配置され、レイアウトされ、表示されたあと、最終的に破棄されるまでの流れ)が載っていますが、そのうち viewWillAppear(_:) の直後に呼ばれます。 ためしに、 override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 呼び出されたメソッド名を表示する print(#function) } のような行を追加して実行すると、よりわかりやすくなるかと思います。
momokoko

2021/02/04 00:24

ありがとうございます。 理解できました。 print(#function) でメソッド名が出力できるのですね。 こちらも勉強になりました。
guest

0

自分はUITableViewControllerやUICollectionViewControllerとかは使いませんが、collectionViewがfetchUserより早く呼ばれのは、ただUICollectionViewControllerを使っているからだと思いますよ。UIViewControllerで試してみれば、collectionView.reloadを呼ばないと、collectionViewはデータを呼ばないので。

投稿2021/02/03 04:01

tomato879241

総合スコア133

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

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

TsukubaDepot

2021/02/03 07:09

UICollectionViewController を使っても、メソッドが呼ばれる順番は (1) viewDidLoad() (2) その内部で呼ばれている super.viewDidLoad() (3) その内部で呼ばれている configureCollectionView() (4) その内部で呼ばれている fetchUser() の順番です。 CollectionView の DataSource が呼び出されるのは、viewWillAppear(_:) が呼ばれた後のタイミングになります。 「なぜcollectionViewメソッドがfetchUserメソッドがより早く呼ばれるのか」の回答は、hoshi-takanoriさんが質問への追記に書かれている通り、fetchUserはネットワーク処理に絡む遅延処理が含まれているためが正しい回答かと思います。
momokoko

2021/02/03 14:24

回答ありがとうございます。 皆様のおかげで理解が進みました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問