2016-05-18 18 views
0

ここで私の考えは、イベントメソッドをボタンに追加する簡単な方法を作成することでした。ハンドラメソッドの#selector Swift 2.2

は私の例に従ってください: Gist

問題は、私はEXC_BAD_ACCESSとの問題を抱えて、おそらく#selectorで実行が安全ではないので、あるんだということです。

これを解決するにはどうすればよいですか?

デバッグ画面: DebugScreen

スタックトレース:

* thread #1: tid = 0x4e8e43, 0x0000000110355547 libsystem_blocks.dylib`_Block_copy_internal + 239, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) 
frame #0: 0x0000000110355547 libsystem_blocks.dylib`_Block_copy_internal + 239 
frame #1: 0x000000010d8c326d Swift-201-Aula2-Exercicio2.1`@objc UICallbackButton.executeCallback(UIButton, callback : (button : UIButton) ->()) ->() + 45 at ViewController.swift:0 
frame #2: 0x000000010e2d4a8d UIKit`-[UIApplication sendAction:to:from:forEvent:] + 92 
frame #3: 0x000000010e447e67 UIKit`-[UIControl sendAction:to:forEvent:] + 67 
frame #4: 0x000000010e448143 UIKit`-[UIControl _sendActionsForEvents:withEvent:] + 327 
frame #5: 0x000000010e447263 UIKit`-[UIControl touchesEnded:withEvent:] + 601 
frame #6: 0x000000010e34799f UIKit`-[UIWindow _sendTouchesForEvent:] + 835 
frame #7: 0x000000010e3486d4 UIKit`-[UIWindow sendEvent:] + 865 
frame #8: 0x000000010e2f3dc6 UIKit`-[UIApplication sendEvent:] + 263 
frame #9: 0x000000010e2cd553 UIKit`_UIApplicationHandleEventQueue + 6660 
frame #10: 0x000000010d9d0301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 
frame #11: 0x000000010d9c622c CoreFoundation`__CFRunLoopDoSources0 + 556 
frame #12: 0x000000010d9c56e3 CoreFoundation`__CFRunLoopRun + 867 
frame #13: 0x000000010d9c50f8 CoreFoundation`CFRunLoopRunSpecific + 488 
frame #14: 0x0000000112140ad2 GraphicsServices`GSEventRunModal + 161 
frame #15: 0x000000010e2d2f09 UIKit`UIApplicationMain + 171 
* frame #16: 0x000000010d8c42c2 Swift-201-Aula2-Exercicio2.1`main + 114 at AppDelegate.swift:12 
frame #17: 0x000000011031292d libdyld.dylib`start + 1 
+0

参照しているstacktraceとコード行を表示します。 – trojanfoe

+0

私は画面で質問を更新しましたが、問題は私がスタックトレースを持っていないことです。 –

+0

デバッグコンソールに 'bt'と入力します。 – trojanfoe

答えて

1

あなたのコードは、夫婦の問題を持って、私は信じています。ボタン上の循環参照は問題ではないかもしれませんが、あなたのコールバックがexecuteCallback(:)メソッドの途中にあるわけではありません。あなたがそれを必要としないことが分かります。コールバックへの参照を保存するだけです。これが意味をなさないかどうかを見てくださいできます。

import UIKit 

class ViewController: UIViewController { 

    var count = 1 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Button 1 
     let button = UICallbackButton(frame: CGRect(x: 60, y: 30, width: 200, height: 60)) 
     button.backgroundColor = UIColor.orangeColor() 
     button.setTitleColor(UIColor.whiteColor(), forState: .Normal) 
     button.setTitle("Title Default", forState: .Normal) 
     button.on(.TouchUpInside, then: { 
      button.setTitle("Title \(self.count)", forState: .Normal) 
      self.count = self.count + 1 
     }) 

     self.view.addSubview(button) 


     // Button 2 
     let button1 = UICallbackButton(frame: CGRect(x: 60, y: 160, width: 200, height: 60)) 
     button1.backgroundColor = UIColor.blackColor() 
     button1.setTitleColor(UIColor.whiteColor(), forState: .Normal) 
     button1.setTitle("Value Default", forState: .Normal) 
     button1.on(.TouchUpInside, then: { 
      button1.setTitle("Value \(self.count)", forState: .Normal) 
      self.count = self.count + 1 
     }) 

     self.view.addSubview(button1) 

    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

} 


typealias ButtonCallback = (() ->()) 

protocol UIActionButton { 

    func on(event : UIControlEvents, then callback: ButtonCallback) 

} 

final class UICallbackButton : UIButton, UIActionButton { 

    var buttonCallback: ButtonCallback! 

    func on(event : UIControlEvents, then callback: ButtonCallback) { 
     buttonCallback = callback 
     self.addTarget(self, action: #selector(UICallbackButton.executeCallback(_:)), forControlEvents: event) 

    } 

    func executeCallback (_ : UIButton) { 
     buttonCallback() 
    } 
} 
0

私はセレクタでそれを行う方法を知りませんが、ここで、それは閉鎖している正直に言うと。テストされ、100%働いています。セレクタを使って解決策を見つけようとします。それほど違いはありません。コントロールイベントの配列を渡すことができ、それはすべてを制御します。

import UIKit 

class ViewController: UIViewController { 

    var count = 1 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // Button 1 
    let button = GIBbutton(frame: CGRect(x: 60, y: 30, width: 200, height: 60), controlEvents: [.TouchUpInside], targetAction: { button in 
     button.setTitle("Title \(self.count)", forState: .Normal) 
     self.count += 1 
    }) 
    button.backgroundColor = UIColor.orangeColor() 
    button.setTitleColor(UIColor.whiteColor(), forState: .Normal) 
    button.setTitle("Title Default", forState: .Normal) 


    self.view.addSubview(button) 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

}

クラスGIBbutton:UIButton { のvarアクション:(!(UIButton) - >ボイド)!

convenience init(frame:CGRect,controlEvents:[UIControlEvents],targetAction:((UIButton!)->Void)!){ 
    self.init() 
    self.frame = frame 
    action = targetAction 
    for event in controlEvents{ 
     self.addTarget(self, action: #selector(GIBbutton.performOurAction), forControlEvents: event) 
    } 
} 

func performOurAction(button:UIButton,completion:(UIButton)){ 
    self.action(self) 
} 

}

関連する問題