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

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

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

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

Q&A

解決済

1回答

2601閲覧

Swift: Callback関数をさらに別の関数へ渡したい

salud

総合スコア215

Swift

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

0グッド

0クリップ

投稿2019/06/22 10:39

編集2019/06/22 11:12

以下のように書いてみましたが、エラーが出ています。
解決方法がわかる方、教えていただけますと幸いです。

やりたいこととしては、
(1) MapViewControllerで、DataManagerのmapメソッドを呼び出し、
APIから情報を更新して、addAnnotationsメソッドを呼びたいと考えています。

// MapViewController.swift class MapViewController: UIViewController, MKMapViewDelegate { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // AppDelegateのインスタンスを取得 self.delegate = UIApplication.shared.delegate as? AppDelegate // DataManagerのインスタンスを取得 self.dataManager = delegate?.dataManager // APIからデータの更新 self.dataManager?.map(callback: self.addAnnotations) // (1) } func addAnnotations() { // } }

(2) 成功すれば、callbackメソッドを呼び出しますが、
(3) 失敗した場合は、一旦loginメソッドを呼び出したあと、
再度mapメソッドをリトライしたいと考えています。

しかし、(3)の位置で、
Cannot convert value of type '()' to expected argument type '() -> Void'
というエラーが出てしまいました。

// DataManager.swift class DataManager { func login(callback: @escaping () -> Void) { // providerAuthNone.request(.login) { result in switch result { case let .success(moyaResponse): do { let filteredResponse = try moyaResponse.filterSuccessfulStatusCodes() callback() } catch { // show an error to your user } case let .failure(error): // break } } } func map(callback: @escaping () -> Void) { providerAuthBearer.request(.map) { result in switch result { case let .success(moyaResponse): do { let filteredResponse = try moyaResponse.filterSuccessfulStatusCodes() callback() // (2) } catch { // show an error to your user self.login(callback: self.map(callback: callback)) // (3) } case let .failure(error): // break } } }

以上です。
よろしくお願い申し上げます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

タイトルと内容がちょっとずれている気がしたのですが、おそらくやりたいこととしては「mapの引数にcallbackを渡した状態のものを、loginのcallbackとして呼ばせるようにしたい」というところでしょうか。

ご提示のエラーの通り関数の型が合わないので、以下のようにクロージャでラップした関数を定義してあげればよいと思います。

swift

1self.login { [weak self] in 2 self?.map(callback: callback) 3}

それと余談ですが、次の書き方には注意です。

swift

1self.dataManager?.map(callback: self.addAnnotations)

self.addAnnotations は暗黙的にselfを強参照でキャプチャしてしまうので、この書き方だと循環参照によるメモリリークが発生する可能性があります。メンバメソッドをcallbackとして渡したいのであれば、冗長には感じるかもしれませんがクロージャでselfのキャプチャの仕方を設定するようにしてください。

swift

1self.dataManager?.map { [weak self] in 2 self?.addAnnotations() 3}

投稿2019/06/23 01:22

編集2019/06/23 05:47
kakajika

総合スコア3131

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問