【问题标题】:buttons generated programmatically crash app when clicked.单击时以编程方式生成的按钮使应用程序崩溃。
【发布时间】:2023-03-17 22:21:02
【问题描述】:

我正在尝试在给定初始值的情况下快速动态生成按钮,大小为 8 的数组将生成 8 个按钮。

但是,即使代码有效,每当我单击任何生成的按钮时,应用程序都会立即崩溃并显示错误代码“线程 1 信号 SIGABRT”,并且控制台显示“libc++abi.dylib:以未捕获的异常终止” NSException 类型”。

然后我被指向 AppDelegate.swift 中包含“class AppDelegate: UIResponder, UIApplicationDelegate {”的行。

我尝试了其他类似问题中的建议,但无济于事,请参见下面的代码

func generateButtons (){

    var numberOfVillains = ["1", "2", "3", "4", "5", "6", "7",  "8", "9", "10"]
    var buttonY: CGFloat = 126  // our Starting Offset, could be 0
    for number in numberOfVillains {
        let segmentController = UISegmentedControl()
        //let villainButton = UISegmentedControl(frame: CGRect(x: 50, y: buttonY, width: 50, height: 30)){
        buttonY = buttonY + 40  // we are going to space these UIButtons 50px apart
        segmentController.frame = CGRect(x:160, y:buttonY, width: 100,height:  30)
        //segment frame size
        segmentController.insertSegment(withTitle: "Off", at: 0, animated: true)
        //inserting new segment at index 0
        segmentController.insertSegment(withTitle: "On", at: 1, animated: true)
        //inserting new segment at index 1
        segmentController.backgroundColor = UIColor.white
        //setting the background color of the segment controller
        segmentController.selectedSegmentIndex = 0
        //setting the segment which is initially selected
        segmentController.addTarget(self, action: Selector(("segment:")), for: UIControlEvents.valueChanged)
        //calling the selector method
        self.view.addSubview(segmentController)
        //adding the view as subview of the segment comntroller w.r.t. main view controller
    }

}

func buttonPressed(sender: UISegmentedControl!) {
    print("ButtonIsSelected")
}

【问题讨论】:

  • 旁注 - 我认为这里有一些风格可以改进您的代码。您将这些称为按钮,但它们不是。您的数组称为numberOfVillains,这令人困惑,因为您希望它是一个数字而不是字符串数组。您的分段控件被命名为segmentController,而不是像segmentedControl 这样稍微更正确/更清晰的名称。改进命名约定将提高代码的可读性和可维护性。如果您实际上并未在任何地方对其进行变异,您的数组也可以更改为 let 常量。

标签: ios swift swift3 uisegmentedcontrol sigabrt


【解决方案1】:

您正在按钮上设置 Selector(("segment:")) 的目标。但是你添加的处理点击的方法叫做 buttonPressed()

将 Selector(("segment:")) 更改为 Selector("buttonPressed:") 应该可以解决问题

【讨论】:

  • 我已经尝试了你的建议,同样的事情发生
  • 您可能还需要使用 @objc func buttonPressed(sender: UISegmentedControl) 对函数进行注释。这迫使它暴露给目标 c 运行时,以便 UIControl 可以调用它。此代码是否在视图控制器中?此外,如果您正在使用的对象在创建按钮后从内存中删除,您也会遇到崩溃。视图控制器在屏幕上时不会从内存中删除。
  • 感谢您的回复,我已经添加了“@objc”,但问题仍然存在,是的,所有这些代码都包含在 UIViewController 中
  • Jeffrey Bergier 的建议应该可以解决问题。我建议提问者在选择器中仔细检查"buttonPressed:" 的拼写和标点符号,确保: 没有被省略。另外,不要忽略编译器警告。
  • 最后一个建议。编译时,您可能会看到警告消息:Use '#selector' instead of explicitly constructing a 'Selector'。所以尝试用#selector(buttonPressed(_:)) 替换Selector(("buttonPressed"))。我经常使用后一种结构,即使只是为了使编译器警告静音。
【解决方案2】:

事情需要看起来像这样:

class ViewController: UIViewController {

  func generateButtons (){
    ...
  }

  @objc func buttonPressed(sender: UISegmentedControl!) {
    print("ButtonIsSelected")
  }

}

不是这样的:

class ViewController: UIViewController {

  func generateButtons (){
    ...
  }

}

@objc func buttonPressed(sender: UISegmentedControl!) {
  print("ButtonIsSelected")
}

另外,要使编译器警告静音,请尝试更改行:

segmentController.addTarget(self, action: Selector(("buttonPressed:")), for: UIControlEvents.valueChanged)

到:

segmentController.addTarget(self, action: #selector(buttonPressed), for: UIControlEvents.valueChanged)

【讨论】:

  • 这是我的 Xcode 中当前设置的方式,如果你有时间,你可以尝试运行它,如果它适合你,那么这意味着问题出在我的代码的其他地方
  • @Riazbapoo 实际上,这是我尝试的第一件事;将您的代码剪切并粘贴到我为此目的制作的新项目中。稍作改动后编译运行成功。 (我仍在使用 Swift 2;您似乎在使用 Swift 3。)您是否尝试按照我的建议将 Selector() 更改为 #selector()
  • 您能否提供一段代码以准确显示必须更改的内容和方式,因为在用您建议的文本替换文本时出现红色编译器错误
  • @Riazbapoo 当然。我已将此附加到我的答案中。
【解决方案3】:

我想我已经找到了问题,显然你为生成的按钮引用的函数不需要包含“:”,也不需要任何括号,如果它不接受任何参数,那么正确的格式是

segmentController.addTarget(self, action: #selector(ViewController.buttonPressed), for: .valueChanged)

相对于

segmentController.addTarget(self, action: Selector(("buttonPressed:")), for: UIControlEvents.valueChanged)'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多