- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个时间计算器来尝试学习 Swift,但我遇到了一个问题,即格式化用户输入会导致访问错误。
这是导致崩溃的代码(最初包含在一个循环中但被分解以试图找到问题):
var outputString : String = ""
let prefixString : String = "00"
let combinedString1 : String = prefixString + self.timeIntervalInput[0]
let combinedString1a : String = combinedString1.substringFromIndex(countElements(combinedString1) - 2)
outputString += combinedString1a
let combinedString2 : String = prefixString + self.timeIntervalInput[1]
let combinedString2a : String = combinedString2.substringFromIndex(countElements(combinedString2) - 2)
outputString += combinedString2a // CRASH USUALLY HAPPENS HERE
let combinedString3 : String = prefixString + self.timeIntervalInput[2]
let combinedString3a : String = combinedString3.substringFromIndex(countElements(combinedString3) - 2)
outputString += combinedString3a
用户的输入存储在一个字符串数组中(小时/分钟/秒/毫秒)。上面的代码应该用 0 填充空白(因此 2 变为 02,空字符串变为 00,等等),并且在每次更新用户输入时运行。
上面的代码在输入第一个或第二个字符后崩溃。将 prefixString 从 let 更改为 var 会导致它正常工作的时间稍长,因此它会在第三个字符后崩溃。
我是不是做错了什么,或者这是 Swift 中的错误?
编辑(附加信息):
这是整个结构:
struct TimeCalcInput
{
var timeIntervalInput : String[] = ["", "", "", ""]
var timeIntervalIndex : Int = 0
var decimalInput : String = ""
var timeType : TimeTypeEnum = TimeTypeEnum.AM
var potentialInput : String = ""
var label : String {
get {
if (self.timeType == TimeTypeEnum.Decimal) {
return self.decimalInput
} else {
// var outputString : String = ""
// for (var i : Int = 0; i < 3; i++) {
// let prefixString : String = "00"
// var combinedString : String = ""
// combinedString += prefixString + self.timeIntervalInput[i]
// combinedString = combinedString.substringFromIndex(countElements(combinedString) - 2)
// outputString = outputString + "\(combinedString)"
// }
var outputString : String = ""
let prefixString : String = "00"
let combinedString1 : String = prefixString + self.timeIntervalInput[0]
let combinedString1a : String = combinedString1.substringFromIndex(countElements(combinedString1) - 2)
outputString += combinedString1a
let combinedString2 : String = prefixString + self.timeIntervalInput[1]
let combinedString2a : String = combinedString2.substringFromIndex(countElements(combinedString2) - 2)
outputString += combinedString2a // CRASH USUALLY HAPPENS HERE
let combinedString3 : String = prefixString + self.timeIntervalInput[2]
let combinedString3a : String = combinedString3.substringFromIndex(countElements(combinedString3) - 2)
outputString += combinedString3a
return ""
let test : String = "000"
var asd : String = test + self.timeIntervalInput[3]
asd = asd.substringFromIndex(countElements(asd) - 3)
outputString += asd
if (self.timeType == TimeTypeEnum.AM) {
outputString += " AM"
} else if (self.timeType == TimeTypeEnum.PM) {
outputString += " PM"
}
println(outputString)
return outputString
}
}
}
mutating func validateNewInput(inputString : String) -> Bool
{
switch (self.timeType)
{
case TimeTypeEnum.Decimal:
return self.validateNewInputForDecimal(inputString)
case TimeTypeEnum.Interval:
// return self.validateNewInputForInterval(inputString)
return false
case TimeTypeEnum.AM, TimeTypeEnum.PM:
var temp : Bool = self.validateNewInputForRawTime(inputString, isMilitaryTime:false)
println(self.timeIntervalInput)
return temp
case TimeTypeEnum.Military:
var temp : Bool = self.validateNewInputForRawTime(inputString, isMilitaryTime:true)
println(self.timeIntervalInput)
return temp
default:
return false
}
}
mutating func validateNewInputForDecimal(inputString : String) -> Bool
{
let combinedString : String = self.decimalInput + inputString
// note: this regex fails on letters-only strings. not an issue now but something to watch
let predicate : NSPredicate = NSPredicate(format: "SELF MATCHES '^[0-9]*(\\.[0-9]*)'")
let stringTest : Bool = predicate.evaluateWithObject(combinedString)
if (stringTest) {
self.decimalInput = combinedString
return true
}
return false
}
// used to evaluate an incoming string when the string is assumed to represent a raw time (e.g. 5:30am)
// since the string is being built one character at a time, each character needs to be evaluated separately
// to ensure that the final time is valid
mutating func validateNewInputForRawTime(inputString : String, isMilitaryTime : Bool) -> Bool
{
let currentString = self.timeIntervalInput[self.timeIntervalIndex]
// if the incoming value is a ":" assume the user wants to move on to the next section
// (e.g. hours --> minutes). Fill in any gaps in the current section, then advance to the next section
if (inputString == ":") {
// check to make sure there is a "next" section
if (self.timeIntervalIndex < self.timeIntervalInput.count - 1)
{
// if the current section is incomplete, fill any gaps with 0s
let prefixString = "00"
var combinedString = prefixString + currentString
combinedString = combinedString.substringFromIndex(countElements(combinedString) - 2)
self.timeIntervalInput[self.timeIntervalIndex] = combinedString
// go to the next section
self.timeIntervalIndex++
return true
}
// if the incoming value is a number, evaluate it to make sure it's valid, and if so, add it
} else {
let combinedString = currentString + inputString
// each section (hours, minutes, etc, has its own rules for whether the input is valid
switch (self.timeIntervalIndex)
{
// hours
case 0:
// if empty, accept any number
if (countElements(currentString) == 0) {
self.timeIntervalInput[self.timeIntervalIndex] = combinedString
return true
// if one digit exists, make sure total value is less than 12/24 (format depending)
} else if (countElements(currentString) == 1) {
if ((combinedString.toInt() < 24 && isMilitaryTime) || (combinedString.toInt() < 12)) {
self.timeIntervalInput[self.timeIntervalIndex] = combinedString
return true
}
// if both digits exist, skip to the next section and add it
} else {
self.timeIntervalIndex++
self.timeIntervalInput[self.timeIntervalIndex] = inputString
return true
}
// minutes, seconds
case 1, 2:
// if empty, accept any number
if (countElements(currentString) == 0) {
self.timeIntervalInput[self.timeIntervalIndex] = combinedString
return true
// if one digit exists, make sure total value is less than 60
} else if (countElements(currentString) == 1) {
if (combinedString.toInt() < 60) {
let combinedString = currentString + inputString
self.timeIntervalInput[self.timeIntervalIndex] = combinedString
return true
}
// if both digits exist, skip to the next section and add it
} else {
self.timeIntervalIndex++
self.timeIntervalInput[self.timeIntervalIndex] = inputString
return true
}
// milliseconds
case 3:
// accept any combined total less than 1000
if (combinedString.toInt() < 1000) {
let combinedString = currentString + inputString
self.timeIntervalInput[self.timeIntervalIndex] = combinedString
return true
}
default:
break
}
}
return false
}
}
这是它被使用的地方(输入是上述结构的数组):
// -----------------------------------------------------------------------------------------------------------------
@IBAction func addInputCharacter(#sender : UIButton)
{
let inputChar : String = String(sender.tag)
self.inputs[self.currentInput].validateNewInput(inputChar)
self.updateLabelsAfterInput()
}
// -----------------------------------------------------------------------------------------------------------------
func updateLabelsAfterInput()
{
self.lblMainLabel.text = self.inputs[self.currentInput].label
if (self.currentInput == 0) {
self.lblSecondaryLabel.text = ""
} else {
self.lblSecondaryLabel.text = self.inputs[0].label
}
}
崩溃发生在用户第一次输入数字时。我在没有更新标签的情况下对其进行了测试,并且 timeIntervalInputs 数组设置完美(输入“1”后,数组读取 [1, , , ],然后输入 0 变为 [10, , , ])
崩溃时的错误信息是
Thread 1: EXC_BAD_ACCESS (code=1, address=0x12aff2cf0)
combinedString2a,就在崩溃之前,正在存储正确的值(“00”)。崩溃后,Quick Look 显示该值为“(None)”并打印描述给出以下消息:
(String) combinedString2a = DW_OP_piece for offset 8: top of stack is not a piece
最佳答案
我一直遇到同样的错误,我只能认为这是 Swift 中的一个错误。这是一个非常简单的例子。 txtName 是文本字段的 IBOutlet,用户可以在其中键入他们的姓名,labResult 是放置结果的标签。在下面的代码中,我们每次尝试调用 .lowercaseString 方法时都会在 modifyString 中遇到错误。 (我是 Swift 和 iOS 编程的新手,所以我可能会犯一些愚蠢的错误,但我不知道是什么)。
@IBAction func butDoIt_Clicked(sender : UIButton) {
var myName = "Fred Bloggs"
labResult.text = modifyString(myName) //this works just fine
if txtName.text
{
myName = txtName.text!
labResult.text = modifyString(myName) //this crashes with EXC-BAD-ACCESS
}
}
func modifyString(aName:String) ->String
{
let lowername = aName.lowercaseString
let uppername = aName.uppercaseString
return lowername + "-" + uppername
}
关于ios - Swift 字符串操作导致 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24208594/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!