このページの本文へ

Swift Playgroundsで学ぶiOSプログラミング第92回

過去に作ったプログラムを最新バージョンに最適化

Swift Playgrounds 2.1での問題点をまとめて解消する

2018年06月20日 17時00分更新

文● 柴田文彦 編集●吉田ヒロ

  • この記事をはてなブックマークに追加
  • 本文印刷

 前回の最初にも述べたように、Swift Playgroundsのバージョンを2.1にアップデートすると、この連載で以前に紹介したプログラムが動作しなくなることがあります。その場合は、決まって「プレイグラウンドの実行中に問題が起きました」というダイアログが表示され、理由もわからずプログラムの実行が停止してしまうのです。

Swift Playgroundsのバージョン2.1では、プログラム自体には問題がないように見えても実行すると途中で「プレイグラウンドの実行中に問題が起きました」というダイアログを表示して止まってしまうことが多くなっています。今回は、この問題を解消します

 これは、いわゆるランタイム(実行時)エラーというものです。プログラムの文法が間違っているというわけではなく、実行前のコンパイル時には見つけられないエラーがあとから発生しているのです。

 Swiftの文法が間違っていたり、フレームワークのメソッドの名前や引数のラベルが間違っていたりする場合には、プログラムを入力する都度チェックが入り、実行前に察知することができます。その場合には、そのエラーの場所と内容はもちろん、修正するためのヒントや候補まで提示してくれるので、納得しながらエラーを正すことができます。

 しかし、ランタイムエラーの場合には、そうはいきません。まず、メッセージからはエラーの場所も内容も分かりません。「コードに誤りがないか確認してください。」と言われても、どこがどう悪いのかわからなければ手の打ちようがありません。エラーが発生する前、最後に実行していた部分は、プレイグラウンドのデバッガ表示をよく見ればわかることもあります。また、表示が確認しやすいコードを埋め込んで、発生箇所をはっきりさせることが可能な場合もあります。それでも、ランタイムエラーの場合には、エラーが発生した場所が原因でエラーになっているとは限りません。それより前に実行した部分に原因がある場合や、利用しているフレームワーク内のメソッドの実行によってエラーが発生することもあり得ます。

 以上は、ランタイムエラーの一般論です。このバージョン2.1以降で発生する実行時の問題に限って言えば、それがバグなのか仕様なのかは別として、Swift Playgroundsのビューコントローラーによるビューの扱い方の変化によって発生するようになったことが強く疑われます。この問題に気づいてから、エラーの発生状況を色々と確認し、その対処方法も開拓してきました。それらの対策はまちまちですが、エラーの根本的な要因は同じところにあるように思えるのです。

 かなり昔に遡りますが、Swift Playgroundsのバージョンが1.6になって、アクションとして実行するメソッドの定義の前に「@objc」が必要となって以降のプログラムをひととおり見直し、典型的なエラーの発生状況とその対策を見ていくことにしましょう。具体的には第59回のイメージピッカー経由でiPadの内蔵カメラを使った写真撮影のプログラムから見直します。

イメージビューは、使うときに初めて作成する

 実は上の図で示した実行エラーの例は、第59回の2番目の例(AsciiClub-59-2)のプログラムで発生したものです。このプログラムでは、ビューコントローラーのプロパティとしてイメージビューのオブジェクトを作成し、viewDidLoadメソッドの中で、それをビューコントローラーのビューとして設定しています。

この連載の第59回に紹介した、iPadの内蔵カメラを使った写真撮影プログラムです。実行前にはエラーは検出されていませんが、「コードを実行」をタップすると上の図のようなエラーが発生して止まってしまいます

 実はこれがまずいのですが、実行時エラーはそこではなく、写真を撮影し終わってイメージピッカーコントローラーのdidFinishPickingMediaWithInfoのメソッドの中で、イメージピッカーのビューを閉じる部分で発生します。それによって、元のビューコントローラーのビュー、つまりイメージビューが表示されるからだと思われます。

 この対処方法は、いろいろと考えられますが、最も簡単なのはイメージビューをビューコントローラーのプロパティとはせずに、写真を撮影後、didFinishPickingMediaWithInfoのメソッドの中で作成しそこに撮影したばかりの画像をセットして、さらにその場でビューコントローラーのビューに設定する方法です。

上のプログラムのイメージビュー(UIImageView)のオブジェクトを作成する場所を変更しています。カメラによる撮影が終了して表示すべき画像が得られてからイメージビューを作成し、そのままそこに画像をセットしています。これでエラーは発生しなくなります

 これは、プログラム自体が実験的なものなので、あまり汎用性のある解決策とは言えないでしょう。しかし、エラーがらみのビューを、なるべくビューコントローラーのプロパティにしないことが有効な場合がある、ということは憶えておくとよいでしょう。

 なお、同じ第59回の1番目の例では、ビューコントローラー自体を使っていないので、エラーは発生しません。

この連載の記事

週間ランキングTOP5

ASCII倶楽部会員によく見られてる記事はコレだ!

ASCII倶楽部の新着記事

会員専用動画の紹介も!