我遇到了一个问题,我无法理解我的生活。我搜索了互联网,试图理解Swifts的EXC_BAD_ACCESS
,但似乎没有任何帮助。
以下代码很长,但大多数时候评论都是了解相关项目所需的全部信息。
我有一个班级CalculatorController
,其中包含以下相关方法和属性:
import UIKit
class CalculatorController: UIViewController {
// the actual `@IBOutlet` which is never accessed directly
@IBOutlet private weak var _mainDisplay: UILabel!
// an instance of `MainDisplayMicroController`
// holds a reference to `_mainDisplay`
// is used to manipulate `_mainDisplay` in a controlled way
private var mainDisplay: MainDisplayMicroController!
override func viewDidLoad() {
super.viewDidLoad()
// connects `mainDisplay` with `_mainDisplay`
mainDisplay = MainDisplayMicroController(label: _mainDisplay)
// sets `_mainDisplay`'s `text` property to "0"
mainDisplay.content = .Number(0)
//...
}
//...
}
为了以某种方式管理_mainDisplay
,我创建了一个类MainDisplayMicroController
,它一方面包含对UILabel
本身的引用,另一方面包含对UILabel
本身的引用。 hand包含方法和属性,它们对import UIKit
class MainDisplayMicroController {
// used to express what `label.text` is currently showing
private enum DisplayState {
case ShowingNumber
case ShowingConstant
case ShowingErrorMessage
case Unknown
}
// holds the current state of what `label.text` is showing
private var state = DisplayState.Unknown
// used to pass different types of values in and out of this class
enum ContentType {
case Number(Double)
case Constant(String)
case ErrorMessage(String)
case Unknown(Any?)
}
// holds the reference to the label which is being manipulated/managed
private var label: UILabel?
// makes `label`'s `text` property directly accessible, as `label` is `private`
var text: String? {
get {
return label?.text
}
set {
label?.text = newValue
removeLeadingZeros()
transformToInteger()
}
}
// a property to allow controlled retrieval and manipulation of `label.text`
// uses `ContentType` to make clear what the information in `label.text` is/ is supposed to be
var content: ContentType {
get {
switch state {
case .ShowingNumber:
if let string = text {
if let value = NSNumberFormatter().numberFromString(string)?.doubleValue {
return .Number(value)
}
}
case .ShowingConstant:
if let symbol = text {
return .Constant(symbol)
}
case .ShowingErrorMessage:
if let message = text {
return .ErrorMessage(message)
}
default:
break
}
state = .Unknown
return .Unknown(text)
}
set {
switch newValue {
case .Number(let value):
text = "\(value)"
state = .ShowingNumber
removeLeadingZeros()
transformToInteger()
case .Constant(let symbol):
text = symbol
state = .ShowingConstant
case .ErrorMessage(let message):
text = message
state = .ShowingErrorMessage
case .Unknown(let thing):
text = "Error: Passed unknown value: \(thing)"
state = .ShowingErrorMessage
}
}
}
// removes the ".0" from `label.text`, if it is a whole number
private func transformToInteger() {
if state == .ShowingNumber {
switch content {
case .Number(let value):
if round(value) == value {
var doubleString = "\(value)"
if doubleString.rangeOfString("e") == nil {
dropLast(doubleString)
dropLast(doubleString)
}
text = doubleString
}
default:
break
}
}
}
// removes leading "0"s from `label.text` if they are redundant
private func removeLeadingZeros() {
if state == .ShowingNumber {
switch content {
case .Number(let displayedValue):
content = .Number(displayedValue)
default:
break
}
}
}
//...
}
:
EXC_BAD_ACCESS
现在,当我运行代码时,我收到以下错误:
从我在NSZombie
上看到的内容,尝试在已发布对象上调用方法时经常会出现错误。我已尝试使用NSZombie
来检查问题,但我没有找到任何内容(可能是因为我使用mainDisplay
时无能)。
如果我试着按照逻辑发生的事情,我会得出以下结论:
viewDidLoad()
已在mainDisplay.content
content
被称为.Number
的setter中,switch-statement执行text
case state
和removeLeadingZeros()
已成功设置content
被称为content
的getter .ShowingNumber
的getter中的switch语句执行NSNumberFormatter
case EXC_BAD_ACCESS
表达式@IBOutlet
有谁知道为什么会这样?是否与我在另一个班级操纵NSNumberFormatter
有关?
非常感谢任何帮助!
以下是指向完整CalculatorController
和MainDisplayMicroController
的链接。
@abdullah建议我尝试将MainDisplayMicroController
表达式指向多个表达式。我仍然得到错误:
我删除了所有引用和外部类,使其尽可能简单,同时保持相同的功能
CalculatorModel
中定义的所有方法和属性都已移至@IBOutlet
现在,这些方法和属性可以访问原始EXC_BAD_ACCESS(code=2)
,而不是对它的任何引用。
但是当我尝试运行它时,我会在同一行代码中得到NSNumberFormatter
我只是非常困惑,因为它与奇怪的引用无关,或者对象过早被释放。
以下是新CalculatorController
的完整代码。
我删除了 node.Rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);
行,将其更改为:
现在我收到以下错误:
我认为代码存在一些基本问题,所以我要废弃它。但感谢所有的帮助,并尝试解决这个问题。
这是我在throw上为所有异常添加断点时得到的结果:
答案 0 :(得分:6)
我真的没有看到任何可能导致崩溃的行。我建议你做以下事情:
答案 1 :(得分:0)
@WarrenBurton正在努力。
从你的大班上撞掉你的线路并在操场上运行它并且工作正常:
let string = "1.213"
if let value = NSNumberFormatter().numberFromString(string)?.doubleValue
{
println("value = \(value)")
}
显示结果
值= 1.213
你的变量在哪里"字符串"你班上定义的?
答案 2 :(得分:0)
请注意,字符串是蓝色的,就像关键字一样,而不是黑色,就像其他局部变量一样。
我尝试使用局部变量string ==> MyString的 只是为了确定。
答案 3 :(得分:0)
Just&#cu; cuz我看到同样的事情,并注意到没有人评论过你的上一次编辑(也许这个问题的Googler同事有一天会看到这个):
对于我们两种情况,问题都是无限递归 - 我们无限地从自身调用一个方法。这就是错误。 A
崩溃的含义是红鲱鱼。