【问题标题】:Swift owned to guaranteed斯威夫特拥有担保
【发布时间】:2015-12-31 10:53:38
【问题描述】:

我刚刚在 xcode 管理器中发现了 5 个崩溃报告。当我打开它们时,我得到了这个堆栈跟踪(标记的区域是我的应用程序的名称):

iOS8.4 和 iOS9 都会出现此错误,iPhone 5 和 iPhone 6 设备同样如此。

我很难追踪,因为我无法在 iPhone5(8.4) 和 iPhone6(9.0.1) 上重现它。

1./2.这里某处:

override func onButtonTableViewCellClick(button: BfPaperButton) {}

3.

var button: BfPaperButton = BfPaperButton.newAutoLayoutView()

func onClick() {
    delegate?.onButtonTableViewCellClick(button) // 3
}

我使用 swift 2、xcode 7 和 iOS9。帮助我理解错误。红色图像的第一行是什么意思?为什么这个错误与Swift.String 有关系??

我找到了这个帖子:https://forums.developer.apple.com/thread/6078 我从中提取了这些信息:

我见过的这种崩溃的一个案例是基于 Obj-C 的对象 调用基于 Swift 的委托方法,参数值为 nil 但 Swift 方法签名不是可选类型。在里面 我看到的情况是,桥接委托方法签名中有一个错误—— 它实际上应该是可选的。这可能是什么 在您的情况下类似(Swift 定义不允许 应该是可选的),或者它可能是 Obj-C 代码中的错误 (不应该产生 nil)。

我使用了一个名为 BfPaperButton 的 obj-c 库,它创建了一个类似于 android 材料设计的 Button。也许错误与这个库有关?

日志:

查看图片:http://i.stack.imgur.com/5aQ8m.png

我有两个字符串扩展。一个用于长度,一个用于子字符串:

extension String {

    var length: Int { return self.characters.count }

    subscript (i: Int) -> String {
        return String(Array(self.characters)[i])
    }

    subscript (r: Range<Int>) -> String {
        let start = startIndex.advancedBy(r.startIndex)
        let end = startIndex.advancedBy(r.endIndex)
        return substringWithRange(Range(start: start, end: end))
    }
}

第 188 行是:

NSUUID().UUIDString[0...4]

使用子字符串扩展。也许错误就在这里?

override func onButtonTableViewCellClick(button: UIButton) {

        if let title = button.titleLabel?.text {

            if title == "Send code" {

                tmpPhoneNumber = ""

                var tmp = phoneNumber

                if tmp.length > 1 {
                    if tmp[0] == "0" {
                        tmp = tmp[1...tmp.characters.count - 1]
                    }

                    tmpPhoneNumber = "0049" + tmp
                    phoneNumberWithCode = tmpPhoneNumber
                    sendAlert(tmp)
                } else {
                    PfToast.showError("Please enter your phone number.")
                }

            } else if title == "Finish" {
                if let cell: InputTableViewCell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 2)) as? InputTableViewCell {
                    if isLicenceValid(cell.inputField.inputField.text!) {
                        createCustomer(cell.inputField.inputField.text!)
                    } else {
                        PfToast.showError("Please enter correct licence plate.")
                    }
                }
            }
        }
    }

【问题讨论】:

  • 日志查看器中的实际错误消息是什么?
  • @l'L'l 你是什么意思?我有组织者视图(请参阅我更新的问题),当我点击“在项目中打开”时,我会看到第一张图片中的日志视图。
  • 你能把thread 0, #1的全文贴出来吗(删掉私人信息很好,只是该行的其余部分被截断了-可能包括发生错误的行)。
  • @l'L'l 看到我的更新(遗憾的是 xcode 不允许复制日志:/)
  • 168 和 188 无关。这些是机器代码偏移量,而不是行号。我们可以从堆栈跟踪中得知您的崩溃在 subscript (i: Int) -&gt; String 中,从 onButtonTableViewCellClick 调用。在该调用者中,subcript 的唯一用途是 if tmp[0] == "0" { 行。您的字符串是否可能以代理对表示的“有趣”Unicode 字符开头?

标签: ios objective-c swift swift2


【解决方案1】:

在我看来,您正在寻找错误的地方。当我查看日志时,我看到的是:

  1. 点击按钮
  2. onButtonTableViewCellClick
  3. Obj-C 到 Swift 内部(您可以在 What's Dead & Exploded in Swift's exception stack? 中了解更多信息)
  4. 通过IntString 编制索引(参见String.subscript.getter (Swift.Int) -&gt; String

我们可以确定崩溃发生在这里的某个地方:

return String(Array(self.characters)[i])

我认为我们可以排除nil,因为这会导致更早的崩溃。您很可能遇到字符索引越界问题。这意味着i 要么是负数,要么高于length - 1(也许你正在索引一个空文本?)

很遗憾,重要的代码在onButtonTableViewCellClick,而你还没有发布。

【讨论】:

  • 谢谢!我在我的问题中添加了一些代码。有帮助吗?
猜你喜欢
  • 2017-07-22
  • 2017-03-24
  • 1970-01-01
  • 2016-02-08
  • 2017-11-13
  • 2015-08-19
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多