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

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

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

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

Q&A

解決済

1回答

593閲覧

asyncAfter(deadline:execute:) の記述の仕方

testyoutatsu

総合スコア29

Swift

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

0グッド

0クリップ

投稿2019/01/18 06:38

編集2019/01/18 09:57

制限時間を設けた簡単なクイズアプリを作っています。

questionメソッドで問題文を表示、時間切れでアラートを表示させるというものです。

以下のようなコードを書きました。

var timer = Timer() var seconds = 50 let workItem = DispatchWorkItem(block: { }) func question() { //Labelに問題を表示する記述 let random = Int(arc4random_uniform(UInt32(hairetsu.count))) //追記 ここから// hairetsuLabel.text = hairetsu[random] let random2 = Int(arc4random_uniform(UInt32(hairetsu2.count))) hairetsuLabel2.text = hairetsu2[random2] //ここまで (変数の名前は実際のコードと変えてます) timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.counter), userInfo: nil, repeats: true) DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: workItem) { //ここでエラーメッセージ self.timeOverAlert(a: random) } } @objc func counter() { seconds -= 1 remainingTimeLabel.text = "残り時間:" + String(seconds) + " 秒" if (seconds == 0) { timer.invalidate() } } func timeOverAlert(a:Int) { let correctAnswer = UIAlertController(title: "【正解】",message: "....(random)", preferredStyle: UIAlertController.Style.alert) let nextAction = UIAlertAction(title: "次へ", style: UIAlertAction.Style.default){ (action: UIAlertAction) in self.seconds = 50 self.remainingTimeLabel.text = "残り時間:" + String(self.seconds) + " 秒" self.question() } correctAnswer.addAction(nextAction) present(correctAnswer,animated: true,completion: nil) }

しかし以下のようなエラーメッセージが出ます。

Argument labels '(deadline:, execute:, _:)' do not match any available overloads

エラーメッセージから記述の仕方が間違っているということだと思うのですが、調べても分かりませんでした。
https://developer.apple.com/documentation/dispatch/dispatchqueue/2300020-asyncafter

どこが間違っているのでしょうか?
よろしくお願いします。

.

.

追記:

if seconds == 0 { timer.invalidate() }

この中にtimeOverAlert()を記述すればいいと思うのですが、question()で生成したランダムな数字(random)をうまく渡すことができませんでした。

わざわざDispatchWorkItemを用いる理由は「次へ」のボタンを配置していて、ボタンを押されたらquestion()を実行します。するとタイマーのインターバルが1秒よりも加速してしまうため、これを解決するためにworkItem.cancelを使いたいと思いました。

.

.

fuzzballさんへの返信:
コードが見づらいと思ったので質問の方にも書きます。

回答ありがとうございます。今回は上のコードを使いたいと思います。
ViewControllerクラス直下に

let workItem = DispatchWorkItem(block: { self.timeOverAlert(a: random) })

を書くと
エラーValue of type '(ViewController) -> () -> (ViewController)' has no member 'timeOverAlert'が出て self. を取るとエラーInstance member 'timeOverAlert' cannot be used on type 'ViewController'; did you mean to use a value of this type instead?が出てしまいます。
こちらはどのようにして解決できますでしょうか?

timeOverAlert(a: Int)内に書けばエラーは出ないのですが、workItem.cancelを使いたいのがnextButtonAlert()内なのでクラス直下に書くまたは他の方法がありましたら教えていただきたいです。
回答を頂いてから色々試してみましたがうまくいきませんでした。
何個も聞いてしまいすみません。

追記に書いた「「次へ」のボタンを配置していて、ボタンを押されたらquestion()を実行します。」この部分がnextButtonAlert()です。

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

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

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

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

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

guest

回答1

0

ベストアンサー

swift

1let workItem = DispatchWorkItem(block: { 2 self.timeOverAlert(a: random) 3}) 4DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: workItem)

swift

1DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { 2 self.timeOverAlert(a: random) 3}

じゃないかな。

ついでに

乱数のその書き方は古いです。.random(in:)を使いましょう。

swift

1Int.random(in: 0..<hairetsu.count)

投稿2019/01/18 06:55

編集2019/01/18 07:02
fuzzball

総合スコア16731

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

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

testyoutatsu

2019/01/18 08:56

回答ありがとうございます。今回は上のコードを使いたいと思います。 ViewControllerクラス直下に ```let workItem = DispatchWorkItem(block: { self.timeOverAlert(a: random) })``` を書くとエラー「Value of type '(ViewController) -> () -> (ViewController)' has no member 'timeOverAlert'」が出て self. を取るとエラー「Instance member 'timeOverAlert' cannot be used on type 'ViewController'; did you mean to use a value of this type instead?」が出てしまいます。 こちらはどのようにして解決できますでしょうか? ```timeOverAlert(a: Int)```内に書けばエラーは出ないのですが、workItem.cancelを使いたいのが```nextButtonAlert()```内なのでクラス直下に書くまたは他の方法がありましたら教えていただきたいです。 回答を頂いてから色々試してみましたがうまくいきませんでした。 何個も聞いてしまいすみません。
fuzzball

2019/01/18 09:30 編集

//定義だけしておいて var workItem: DispatchWorkItem? //使うときに代入する workItem = DispatchWorkItem(block: { self.timeOverAlert(a: random) }) あと、質問のコードを見る限りでは、乱数は timeOverAlert() の中で生成してもいいように見えますが、端折ってるコードがあるんですかね。
testyoutatsu

2019/01/18 09:52

「定義だけしておいて...使う時に代入する」で解決できました。ありがとうございます。 question() 内のコードは端折ってる部分があり、question() 内で生成した乱数をもとに配列から問題を選びラベルに表示しています(この部分を書くのを忘れてました)。そのときに生成された乱数をそのまま timeOverAlert() と nextButtonAlert() アラートにも表示させたいと思っています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問