Xcode8 – Swift3への変換MEMO (2):ボタンを押したらクラッシュするようになった

スポンサーリンク

変換後、エラーをすべて解決し、ようやくビルドに成功するようになった!と思ったら、今度は実行後にさまざまな問題が起こります。

ボタンを押したらクラッシュするようになってしまった。。(あるいは無反応)

これもXcode8で新規に作成したプロジェクトでは起こらず、Xcode7以前で作成したプロジェクトをXcode8で開いた場合に起こるものだと思われます。

シミュレータで実行し、ボタンを押すと

unrecognized selector sent to instance 0xXXXXX

とか言われてクラッシュします。つなぎ方によっては無反応というケースもあるようです。

00

@IBActionで紐付けたメソッドが外れている感じ

アシスタントエディタとストーリーボード上のボタンをよく見てみると、どうも紐付けらていた関係が外れているような感じに見えます。これは、紐付いているもののアシスタントエディタが正しく認識できていないような状態なのではないかと思います。

01

この関係を修復してあげればクラッシュしなくなります。

直し方は2通りあるようです。圧倒的に修復法1の方がいいと思います。

修復法1:@IBActionメソッドに「_」をつけるだけ

試しにXcode8で新規に作るとどうなるのか、@IBActionメソッドをつってみる(ストーリーボード上のボタンからアシスタントエディタで開いたコード上にドラッグして作成)と、Xcode7までで作成していたメソッドと若干違いがあります。

04

またお前か!って感じですが、「_」がついてます。こいつがついてないと、senderが誤って認識されるんだと思われます。手書きで「(」のすぐ後に「_」と付け加えておいてあげましょう。

これを書き足した直後は、まだアシスタントエディタも紐付いたことが認識できていないままのようですが、一度ビルドすると認識されるようになります(メソッドの横にある「◯」が「◎」になります)。ソースコード全体をみて、@IBActionとついてるメソッドを同様に修正してあげるとどれも動作するようになるんじゃないかと思います。「(sender:」でコード検索して@IBActionのついてるものを全部修正しちゃいました。

(これらは、Convert時やエラー修正時になんらかの原因で「_」がつかないままになっていたんだと思います。)

修復法2:ソースコードはそのままでストーリーボードとアシスタントエディタで紐付け直す

こちらはなんらかの事情で、ソースコードを書き換えられない(書き換えたくない)ような時の方法ですかね。

アシスタントエディタの対象となる@IBActionメソッドの左側にある「◯」にカーソルを持っていくと「+」になり、ドラッグできるようになります。(これ、Xcode6あたりではドラッグできていたものの、Xcode7あたりでドラッグできなくなってたと思いますが。。)

そこからロープを引っ張って、ストーリーボード上のボタンの上にドラッグします。(他にも再度紐付ける方法はありますが)

02

すると、以前の関係を残したまま、2重にそのメソッドにリンクが貼られてしまいます。ストーリーボード上でボタンを選択している状態で、コネクションインスペクタを見ると確認できます。この方法で紐付けたものは、

メソッド名 + 「WithSender」

と「WithSender」がつくようです。こちらを残して古い方を「X」を押して削除しときましょう。

03

この繋ぎ直し操作をキャプチャしておきました。

ボタンを押したらクラッシュするようになった from mushikago on Vimeo.

こちらの方法でもクラッシュせずに動作するようになったと思います。

Xcode8での@IBActionの形

つまり、Xcode8の標準では、

@IBAction func メソッド名(_ sender: AnyObject) {

と「_」をつける必要があり、Xcode7以前の@IBActionメソッドの形のものを紐付けると「WithSender」とつくことで一応動作できる、という感じですね。