0

最近、アプリを Swift 2.0 に更新し始めましたが、SO に関する 100 の異なる回答がある問題に遭遇しました。どれも私の問題に関連しているようには見えませんでした。

(これは、アプリケーションを Swift 2.0 に更新する前に機能しました)、しかし、ジェスチャ認識機能をタップするために行われた変更を見つけることができませんでしたか?

これが私が得ている完全なエラーです:

[Stocks.Sid​​ePanelViewController proFormulaTapGesture]: 認識されないセレクターがインスタンス 0x14f06ae00 に送信されました

キャッチされない例外 'NSInvalidArgumentException' によるアプリの終了、理由: '-[Stocks.Sid​​ePanelViewController proFormulaTapGesture]: 認識されないセレクターがインスタンス 0x14f06ae00 に送信されました'

*** First throw call stack: (0x1830904d0 0x197afff9c 0x1830971ec 0x183094188 0x182f9920c 0x188c3c58c 0x188899b50 0x18872d104 0x188c3bc30 0x1886ed28c 0x1886eb3ac 0x18872b088 0x18872a5ec 0x1886fb908 0x1886f9fac 0x183047d6c 0x183047800 0x183045500 0x182f75280 0x18e0ec0cc 0x188762df8 0x100158184 0x1983428b8) libc++abi.dylib: terminating with uncaught exception of type NSException

シンプルなタップジェスチャです。しかし、もうセレクターを認識していないようです。

認識エンジンを設定するために使用するコードは次のとおりです。

let proFormulaTap = UITapGestureRecognizer()

proFormulaTap.addTarget(self, action:"proFormulaTapGesture")
proFormulaView.addGestureRecognizer(proFormulaTap)

実行しようとしている関数は次のとおりです。

func proFormulaTapGesture() throws {
        print("proFormulaTapGesture")
        selectView(proFormulaView)
        selectedMenuItem = 0
        Formula = 1
        menuTabBarController.selectedIndex = 0
        navigationController?.navigationBar.topItem!.title = "BASIC FORMULA"
        try (menuTabBarController.viewControllers as! [SuggestionsViewController])[0].loadSuggestions()
    }

ただし、コンソールに「proFormulaTapGesture」が出力されることはありません。私は間違いなく関数の前にエラーが発生すると思います。セレクターに言及しているエラーによっても示唆されています。

明らかに、Swift 2.0 への更新以降、関数に try/catch が追加されていますが、tapGestureRecognizer の設定は何も変更されていません。

「スロー」を削除して関数から試してみましたが、問題は解決しません。また、タップ ジェスチャ レコグナイザーの代わりにボタンを作成してみました。しかし、それでも同じエラーが発生します。これは、タップ ジェスチャ/ボタンではなく、セレクタ (関数) に問題がある可能性があることを示唆しています。しかし、アプリの他のボタンはすべて正常に動作しますか?

また、セレクター/機能とタップジェスチャ認識エンジンの名前を変更しようとしました。まだ同じ。

元のコードは、Obj-C ではなく Swift でプログラムされていました。throws と try は、Apple の Swift 2.0 へのコード変換中に追加されました。

これが突然壊れた理由についての助けをいただければ幸いです。

ありがとう!

4

1 に答える 1

5

throws問題は、少なくともこのコンテキストでは、UIKit がセレクターを呼び出す方法を認識していない可能性があります。

UIKit は、タップ アクションに応答してこの関数を呼び出すことに注意してください。関数を呼び出すことに慣れていませんthrows。明らかにthrow、Objective-C ランタイムに関する限り、メソッドの呼び出しシグネチャを変更する必要があります。さらに、関数proFormulaTapGestureがエラーをスローした場合、エラーをキャッチできたとしても、UIKit はエラーに対して何をするでしょうか?

do/ try/をどこに追加したのかわかりませんcatch。しかし、それが action function 内にない限り、それがproFormulaTapGestureどのように関連するのかわかりません。内部でtry/エラー処理を実装する必要があると思います。これにより、エラーが効果的に飲み込まれ、スローされなくなります。catchproFormulaTapGestureproFormulaTapGesture

自分で簡単なテスト プロジェクトを作成したところ、throwターゲット アクションを実行すると、同じ「認識されないセレクター」エラーが発生することがわかりました。

override func viewDidLoad() {
    super.viewDidLoad()

    self.tapper = NSClickGestureRecognizer(target: self, action: "didClick")
    self.view.addGestureRecognizer(self.tapper!)
}

func didClick() throws {
    print("did click")
}

2015-07-27 00:16:43.260 Test1[71047:54227175] -[Test1.ViewController didClick]: 認識されないセレクターがインスタンス 0x6000000c5010 に送信されました

...

エラーがスローされないように、アクション関数の内部でエラーを処理するためにコードを作り直す必要があると思います-次のようなもの:

func proFormulaTapGesture() {
    print("proFormulaTapGesture")
    selectView(proFormulaView)
    selectedMenuItem = 0
    Formula = 1
    menuTabBarController.selectedIndex = 0
    navigationController?.navigationBar.topItem!.title = "BASIC FORMULA"
    do {
        try (menuTabBarController.viewControllers as! [SuggestionsViewController])[0].loadSuggestions()
    } catch {
        // Handle the error here somehow
    }
}

proFormulaTapGestureでエラーを処理できない場合は、関数の外にそれを渡すことで、より創造的になる必要があります (NSNotification などを考えてください)。


明確にするために、Xcode 7 ベータ 4 で新しい Single View iOS アプリケーションを作成し、この正確なコードを ViewController として使用しました。その他の変更はありません。アプリはコンパイルされ、iOS シミュレーターで問題なく動作します。

@robertvojta は、didTap以下がマークされている場合、動的ディスパッチのクラッシュを回避するためにも必要であることを指摘しています。private@objc

import UIKit

class ViewController: UIViewController {

    var tapper: UITapGestureRecognizer?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tapper = UITapGestureRecognizer(target: self, action: "didTap")
        self.view.addGestureRecognizer(self.tapper!)
    }

    func didTap() {
        print("did Tap")
    }

}

(以前の回答で使用したコードであるOS Xプロジェクトでもテストしたことに注意してください)。

于 2015-07-27T05:27:12.300 に答える