简体   繁体   中英

UIButton throwing Thread1: EXC_BAD_ACCESS (code=1, address 0x…) in Swift

I am creating a UIButton in another file opposed to the main ViewController. I created this button

var newNoteButton = UIButton(frame: CGRectMake(5, 18, 152.5, 37))
newNoteButton.backgroundColor = UIColor.grayColor()
newNoteButton.addTarget(self, action: ("newNoteButtonAction:"), forControlEvents: UIControlEvents.TouchUpInside)
newNoteButton.setTitle("New Note", forState: UIControlState.Normal)
newNoteButton.userInteractionEnabled = true
self.view.addSubview(newNoteButton)

with action

func newNoteButtonAction (sender: UIButton!){
    println("New Note")
}

It is throwing the above error even though, if i copy and paste the same code into my ViewController, it doesn't flag me at all. Why is it doing this? It is meant to just print out the string "New Note" but something causes Thread 1 to queue.

Edit: After a bit of reading, I have been able to reduce the amount of code to just this:

    var newNoteButton = UIButton(frame: CGRectMake(5, 18, 152.5, 37))
    newNoteButton.backgroundColor = UIColor.grayColor()
    newNoteButton.addTarget(self, action: ("newNoteButtonAction:"), forControlEvents: UIControlEvents.TouchUpInside)

and this:

func newNoteButtonAction (sender: UIButton!){
    println("New Note")
}

I tried removing the action and the problem was still there. This exists within my textView class in a separate file. In my AppDelegate file, the Root View Controller is ViewController. If I move the button to ViewController, the issue does not present itself. The only code in my ViewController is this

import Foundation
import UIKit

class ViewController: UIViewController, UITextViewDelegate, UIScrollViewDelegate {

init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
//Global Variables
var scrollView = UIScrollView()

override func viewDidLoad(){
    super.viewDidLoad()

    //Add textView
    //let textViewRef = textView() Removed to test
    //self.view.addSubview(textViewRef.view)

    //Button Code
    var newNoteButton = UIButton(frame: CGRectMake(5, 18, 152.5, 37))
    newNoteButton.backgroundColor = UIColor.grayColor()
    newNoteButton.addTarget(self, action: ("newNoteButtonAction:"), forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(newNoteButton)

}

func newNoteButtonAction (sender: UIButton!){
    println("New Note")
}

}

I have tried messing about with conditionals and the semicolon in the action but that doesn't seem to affect it or help in any way. If you need any more information, please feel free to ask.

Edit 2

My other View Controller looks like this:

import Foundation
import UIKit
class textView: UIViewController {
//Globals
var newNoteButton = UIButton()

override func viewDidLoad() 

    newNoteButton = UIButton(frame: CGRectMake(5, 18, 152.5, 37))
    newNoteButton.backgroundColor = UIColor.grayColor()
    newNoteButton.addTarget(self, action: ("newNoteButtonAction:"), forControlEvents: UIControlEvents.TouchUpInside)
    self.view.addSubview(newNoteButton)

}

func newNoteButtonAction (sender: UIButton!){
    println("New Note")
}
}

Edit 3: I just noticed that this information might be a bit relevant. The error is on the class AppDelegate line in my delegate file.

I had the same problem and I received the same error that you. I wanted create a button in other class. I recommend you read my solution: How invoke a method in the method addTarget of the Button class when I create programmatically the button in a plain class in Swift . An abstract, you should inherit of the "UIClass" that you require. If you want to create a button, you should inherit of "UIButton" class. Then, you set the values of the attributes of this class instead of create a button.

FYI for anybody with this issue in the future, it can usually be debugged back to the retention of the button within the class you are adding the target to.

Try moving the declaration of the button or targeted class up to a class global to be cleaned up after the view is disposed of.

Example: In the instance listed above, declare the newNoteButton at the class level instead of inside the viewDidLoad function to ensure it's retained while it can call it's target.

class ViewController: UIViewController, UITextViewDelegate, UIScrollViewDelegate {

    // Global Variables
    var scrollView = UIScrollView()
    var newNoteButton: UIButton! // <- Declare button here instead of in viewDidLoad

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM