2016-11-17 4 views
4

xcode 8.1/swift 3に問題があります。デバッガXCodeソフトウェアのバグかもしれませんが、行方不明私はUITextFieldで使用されるバックスペースメソッドをオーバーライドする必要があるiosアプリケーションで作業しています。バックスペースキーが押されているのを見るためにデリゲートをセットアップしました。このプログラムは、オーバーライドされたメソッドでデバッガブレークポイントを設定するまで機能します(下記のコードを参照)。私がこれを行うと、バックスペースメソッドは、キーを1回押すのではなく、2回押すごとに2回呼び出されます。ブレークポイントを削除すると、コードが機能します。これは単なるバグですか、何か間違っていますか?あなたの助けのためにコードありがとうございます!ここでデバッガのブレークポイントを持つXcode 8.1/Swift 3.0でdelegateメソッドが2回呼び出されました

import UIKit 

class ViewController: UIViewController, EqFieldDelegate { 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let newField = EqField() 
    newField.myDelegate = self 
    newField.becomeFirstResponder() 
    view.addSubview(newField) 
    newField.frame = CGRect(x: 50, y: 50, width: 200, height: 150) 

} 

func backspacePressed(){ 

    print("in backspacePressed") // breakpoint added here 
} 

} 

はUITextFieldののサブクラスである:

import UIKit 

class EqField: UITextField { 

    var myDelegate: EqFieldDelegate? 

    override func deleteBackward() { 
     super.deleteBackward() 
     myDelegate?.backspacePressed() 
    } 
} 

protocol EqFieldDelegate { 
    func backspacePressed() 
} 
+0

あなたはそれが2回呼び出されていると思いますか?ブレークポイントにヒットしてもヒットし続けると、再びヒットします。それとも具体的には? – TheValyreanGroup

+0

私は提供されたコードでテストプロジェクトを作成し、検証することができます。ブレークポイントに2回ヒットするだけでなく、ログも2回印刷されます。ブレークポイントがなければ、ログは1回印刷されます。 – charmingToad

+0

XCodeデバッガで発生することがあります。 UI要素とその代理人を操作すると、デバッガが誤動作することがあります。 –

答えて

1

私はこれが起こっている理由について、理論を持っています。

説明すると、われわれ自身の戻るボタンを作っているとします。 、

  1. タッチでタッチダウンはまだダウンしている場合は、0.5秒後にbackspacePressed
  2. を呼び出し、タッチすると、すべての0.1秒後に再び
  3. backspacePressedを呼び出します。これは、Appleのを模倣するには、次の行動を持っている必要がありますまだダウンしている、ここで私はそれを実装する方法をですbackspacePressed再び

を呼び出す:

  1. コンソールは、この実験

    func backspacePressed(){ 
        //print("in backspacePressed") 
    } 
    
  2. のための鉱山と一致するように、あなたのログをコメントアウト viewDidLoad

    var buttonTimer: Timer? 
    
    func handleButtonTouched(button: UIButton) { 
        buttonTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: { [weak self] timer in 
    
         print("button's been held down for a while!") 
         self?.backspacePressed() 
    
         self?.buttonTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { (timer) in 
          print("button's still held down") 
          self?.backspacePressed() 
         }) 
    
        }) 
        print("button was pressed") // add a breakpoint here 
        self.backspacePressed() 
    } 
    
    
    func handleButtonReleased(button: UIButton) { 
        buttonTimer?.invalidate() 
    } 
    
  3. (オプション)の後にこれを追加あなたのviewDidLoad

    let button = UIButton(type: .system) 
    button.setTitle("Tap Me", for: .normal) 
    button.addTarget(self, action: #selector(ViewController.handleButtonTouched(button:)), for: .touchDown) 
    button.addTarget(self, action: #selector(ViewController.handleButtonReleased(button:)), for: .touchUpInside) 
    button.frame = CGRect(x: 50, y: newField.frame.maxY, width: 200, height: 150) 
    view.addSubview(button) 
    
  4. の終わりにこれを追加

あなたは、このボタンをタップすると、保持している場合、ブレークポイントがなければ、あなたは私が先に概説動作以下、印刷ログ取得します:あなただけのボタンをタップすると

button was pressed 
button's been held down for a while! 
button's still held down 
button's still held down 
button's still held down 
button's still held down 

を(それを保持していない)、あなた'LL

button was pressed 
button's been held down for a while! 

あなたが思うだろう:ちょうどあなたはブレークポイントを設定した場合、ボタンをタップし、続け押す前に、ブレークポイントのヒット後の第二のを待つ、しかし

button was pressed 

を取得するには、次の2つのログを取得します、siあなたはボタンを長押ししていないので、2番目のログは取得できません。何が起こっているのは、ブレークポイントで停止していてもタイマーが下降しており、実行がプログラムに戻ると、ボタンのリリースが評価される前にタイマーの結果が評価されます。

なぜこのようなことが起こるのか正確にはわかりません。なぜ、タイマーイベントの前にボタンリリースを処理できないのですか?しかし、がブレークポイントなしで正常に実行されていることがわかります。何が先に起こるのかという疑問さえありません。短いボタンをタップすると、タイマーがオフになる前にhandleButtonReleasedが呼び出されます。

あなたのケースでは、アップルのキーボードが何か似たようなことをしていると思われます。タイマーがそうだと判断している間、ブレークポイントを設定しています。本当にそうではありませんが。私は回避策はありませんが、うまくいけば、これは何が起こっているかについてのいくつかの光を照らす。

+0

あなたのコメントと洞察をお寄せいただき、ありがとうございます。私はこれがxcode 7で起こっているとは思わないので、彼らが導入した何か新しいものでなければならないが、私はテストするこのバージョンを持っていない。私は本当に私の代議員が正しくセットアップされたかどうか、または私が気付いていなかった何かが迅速に変わったかどうかを検証しようとしていました。私は今、デバッグのためにコンソールにprintステートメントを使用すると思います。( – siege097

+0

私のマシンでは、これはXcode 7.3.1とXcode 8.1の両方で発生します。デリゲートが正しく設定されていると思いますブレークポイントを使用してデバッグすることはできますが、バックスペースイベントが既に処理されている場合は、バックスペースイベントを無視するようにコードを記述します。 – charmingToad

関連する問題