【问题标题】:Function running faster on iOS simulator than on iPhone在 iOS 模拟器上运行的函数比在 iPhone 上运行得更快
【发布时间】:2015-04-09 04:32:51
【问题描述】:

我遇到了一个奇怪的问题。我正在使用第 3 方 Web API,它应该返回一个未正确设置的 JSON 对象。因此,我必须重新格式化“JSON”,以便 Swift 将其识别为 JSON 对象。在 iOS 模拟器上,重新格式化 JSON 字符串的过程大约需要 2 秒,但是当我在我的物理 iPhone 上测试它时,需要高达 25 秒。为什么是这样?我该如何修复它(使 JSON 格式化程序在物理设备上更快)?

可以在此处看到有缺陷的 JSON:http://godaven.com/db/davenapi.aspx?zip=48075&results=20。在运行我的格式化函数之前,Swift 不会将它注册为 JSON 对象。

这是我用于重新格式化的代码(我找到了一个 javascript 版本,并将其移植到 swift):

func formatJSON(json: String) -> String
{

    var i = 0, il = 0, tab: Character = "\t", newJson = "", indentLevel: Double = 0, inString = false
    var newString = json.stringByReplacingOccurrencesOfString("davenresults = ", withString: "", options: .allZeros, range: nil)
    var jsonArray = Array(newString)

    for(i = 0; i < jsonArray.count; i++)
    {
        var currentChar = jsonArray[i]

        switch(currentChar)
        {
        case "{":
            if (!inString)
            {
                newJson += "\(currentChar)\n\(tab * (indentLevel + 1))"
                indentLevel++
            }
            else
            {
                newJson += String(currentChar)
            }
        case "[":
            if (!inString)
            {
                newJson += "\(currentChar)\n\(tab * (indentLevel + 1))"
                indentLevel++
            }
            else
            {
                newJson += String(currentChar)
            }
        case "}":
            if (!inString)
            {
                indentLevel--
                newJson += "\n\(tab * indentLevel)\(currentChar)"
            }
            else
            {
                newJson += String(currentChar)
            }
        case "]":
            if (!inString)
            {
                indentLevel--
                newJson += "\n\(tab * indentLevel)\(currentChar)"
            }
            else
            {
                newJson += String(currentChar)
            }
        case ",":
            if (!inString)
            {
                newJson += "\(currentChar)\n\(tab * indentLevel)"
            }
            else
            {
                newJson += String(currentChar)
            }
        case ":":
            if (!inString)
            {
                newJson += ": "
            }
            else
            {
                newJson += String(currentChar)
            }
        case " ":
            if (inString)
            {
                newJson += String(currentChar)

            }
        case "\n":
            if (inString)
            {
                newJson += String(currentChar)
            }
        case "\t":
            if(inString)
            {
                newJson += String(currentChar)
            }
        case "\"":
            if (i > 0 && jsonArray[i - 1] != "\\")
            {
                inString = !inString
            }
            newJson += String(currentChar)
        default:
            newJson += String(currentChar)
        }
    }
    return newJson
}

【问题讨论】:

  • 查看用于修复 json 的代码会有所帮助。另外,您使用的这个有缺陷的 json 有多长时间了?可能是你的工作效率很低。
  • 我把JSON前面的“davenresults =”去掉了,然后是有效的(根据一个在线的JSON验证器)。
  • 没错。当我重新格式化时,我并没有想到只把那部分拿出来。刚才,我试着把那部分去掉而不做整个重新格式化的事情,它在手机和模拟器上都在不到一秒钟的时间内工作。我现在觉得自己像个白痴。感谢您的帮助,我很感激。

标签: ios iphone json swift


【解决方案1】:

一个更简单的解决方案是只删除开头的“davenResults =”,这就是导致它无效的 JSON 的原因,它必须包含单个 JSON 对象或数组。

json = result.stringByReplacingOccurrencesOfString("davenresults =", withString:"")

函数的其余部分只是漂亮地打印和缩进 JSON,这对其可解析性没有影响。

您正在进行的处理非常复杂,并且由于重复附加到最终长度为许多 k 的字符串而导致运行效率非常低。

至于为什么两者之间的处理时间如此不同,模拟器以桌面速度运行并且具有桌面处理能力,而真实设备则不然。这是它是“模拟器”而不是周期精确的“模拟器”的原因之一

【讨论】:

    【解决方案2】:

    我认为你不能。因为模拟器与您的实际设备相比具有更高的处理能力。因此,与您的 mac 系统相比,在移动设备中完成该过程需要时间。

    【讨论】:

    • @DaniM.Smith 你不能在手机上让它比在模拟器上更快,但这并不意味着你不可能在两者上都加快速度。这取决于您当前代码的优化程度。
    猜你喜欢
    • 2016-05-12
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2019-12-11
    • 1970-01-01
    • 2014-09-03
    • 2017-01-03
    相关资源
    最近更新 更多