Swift - 除非我关闭优化,否则发布构建崩溃

Posted

技术标签:

【中文标题】Swift - 除非我关闭优化,否则发布构建崩溃【英文标题】:Swift - release build crashes unless I turn off optimization 【发布时间】:2015-03-17 18:46:28 【问题描述】:

这是在 XCode 6.2 上。

如果我在发布模式下运行应用程序,它会崩溃,但如果关闭优化,它不会崩溃。代码看起来很简单。我已经为 ObjC 编程了十多年,所以对编程等并不陌生。

我注意到在 32 位中它在发布模式下运行良好(Fastest -O),但在 64 位真正的 ios 硬件上它会崩溃。

这是编译器错误吗?或者是否有可能只有一些编译器设置崩溃(这可能发生在 C 中!)。

我包含了代码,但我不确定它是否会有所帮助。

class func attemptLogin(completionHandler: (result: JSON?, error: NSError?) -> ()) 
    // It appears that these variables are not working in the completion block in 64 with optimization on.
    let email = User.email
    let password = User.password

    // setup login.
    let parameters: [String : AnyObject] = [
        "action": "login",
        "login": [
            "email": email,
            "password": password,
            "type": User.type
        ]
    ]

    // Fire off REST POST Async
    request(.POST, baseUrl, parameters: parameters, encoding: .JSON)
        .responseSwiftyJSON  (request, response, jsonDict, error) in

                // in release mode on 64 bit, things are seriously bad here. 
            println("jsonDict login attempt: ")
            print(jsonDict)

            if let token = jsonDict["login"]["token"].string 
                println("token found is: " + token)
                User.token = token;
                User.email = email;
                User.password = password;
                completionHandler(result: jsonDict, error: nil)
             else 
                println("No Token")
                User.token = "";
                User.email = "";
                User.password = "";

                let errorNS = NSError(domain: "stethIoUser", code: 404, userInfo: nil)

                completionHandler(result: jsonDict, error: errorNS)
            
        

【问题讨论】:

您的“用户”在此处尝试访问时可能未初始化由于各种优化。它发生在我身上一次。确保在使用“attemptLogin”之前初始化所有变量和类。 ***.com/questions/28153119/… 我认为是相关的 埃里克。谢谢会看,但 User.email 是一个类方法,所以不需要初始化。 可能是这个已知的错误:openradar.appspot.com/radar?id=5257829237653504 【参考方案1】:

我昨天也遇到了类似的情况。

我运行的是 Xcode 6.2。

如果我在发布模式下运行我的应用程序,它会崩溃,但如果关闭优化,它不会在发布模式下崩溃。 (在调试模式下它运行良好。)

问题?这行代码:

let parts = split(columnLetters,  $0 == "," )

是的。就是这样。 split 函数根本没有拆分我的字符串。相反,它将整个原始字符串分配给部件数组的第一个元素。毫不奇怪,这导致应用程序稍后崩溃。

我用这个替换了那行代码,它起作用了:

let parts = columnLetters.componentsSeparatedByString(",")

由于以下原因,此错误特别难以追踪:

    应用程序在测试期间运行良好,因为它是在调试模式下编译的。花了一些时间消除其他因素(iOS 版本、产品与测试数据),才意识到崩溃只发生在发布模式。

    如果我们关闭优化,应用程序会在发布模式下运行。

    崩溃与自两个月前部署的上一个成功发布版本以来引入的任何新代码无关。到目前为止,我们一直在使用 split 函数没有问题。

    出现问题的代码行没有发生崩溃。由于字符串没有被拆分,它稍后在应用程序中发生。

    代码在发布模式下编译良好。没有指向 split 函数问题的编译错误。该函数根本没有拆分字符串。

我尚未在 Xcode 6.3 或更高版本上对此进行测试。 (由于其他原因,我们无法升级到 Xcode 6.3 / Swift 1.2,但很快就会升级。)

【讨论】:

如果您在尝试使用最新编译器时仍然可以重现问题,请不要忘记向 Apple 提出错误 :)【参考方案2】:

我也遇到过类似的情况。由于我相信大多数提出这个问题的人都在寻找更多关于可能导致此问题的原因的见解,因此我将分享我的代码发生的情况。

我在我的项目中使用 ReactiveCocoa,并且我设置了一个响应信号,以便在我有 UIView 的选定声明更改时触发。它是模仿按钮的自定义视图,但实际上源自UIView。在这个块中,我将视图中的所有其他类似按钮的视图设置为将它们的选定状态设置为NO

没有优化,这执行得很好。通过优化,它陷入了无限循环。很奇怪吧?

简而言之,在我的场景中,我更改了这段代码:

[allButtons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];

到这里

for(MyButtonLikeView* button in allButtons) 
    if(button.selected) 
        button.selected = NO;
    

我知道这不太可能解决您的问题。但我希望它有用。

总之,使用您的调试器并留意在 Debug 中正确但在 Release 中可能突然停止工作的代码。

【讨论】:

我刚刚在 Swift 5 和 Xcode 10.3 中遇到了类似的情况,我不得不将一个非常好的“guard var dict = event.getDict() else ”更改为“var dict = event.getDict (); if dict == nil " 第一个因 AppStore 优化编译而崩溃......我刚刚投票支持你回到 0

以上是关于Swift - 除非我关闭优化,否则发布构建崩溃的主要内容,如果未能解决你的问题,请参考以下文章

如何在 IOS 应用程序上检查网络连接? [关闭]

构建:除非提供“--jsx”标志,否则无法使用 JSX

发布构建崩溃、Swift、Armchair 框架、Xcode 6.2

除非我“强制关闭”应用程序,否则在 Windows 中看不到由 Android 应用程序在 SD 卡上写入的文件

除非我关闭我的表单,否则我的代码不会运行,但是我需要打开我的表单,因为我想显示来自其他代码的信息

快速滚动时带有 AlamofireImage 的 Swift UItableview 崩溃