Swift behaves differently on debug and release mode

一个人想着一个人 提交于 2019-12-05 15:57:44

问题


Not sure if that's an issue with Swift, XCode or Alamofire but I recognized strange behavior on different places within my mixed Swift/Objc app. It only happens in parts which are written in Swift and use closures/networking. Here's an example code where it happens:

Alamofire.request(.DELETE, "http://someUrl.com/user", parameters: nil)
     .response { (request, response, data, error) in
                 // some cleanup code and an alert
               }

When I run my app in Debug mode on my iPhone then it all just works, the cleanup code and the alert get presented like they should when I do the "delete account" action which runs the code above.

But when I send my app to users via Testflight or run my app on the same iPhone directly but using the Release build configuration then the cleanup code doesn't run and the alert doesn't show up. It looks like the whole closure doesn't get called.

Does anyone have experiences with such strange behaviors and knows how to prevent them? I'm not sure what's the issue here, therefore it is hard for me to figure out a solution that works on both Debug and Release modes.

Thank you for any help!

The environment: I'm using Alamofire 1.1.3 as an embedded framework integrated to my project as a git submodule. The app runs on iOS 8+ only, I have iOS 8.1.2 installed on my iPhone 6.


回答1:


I've had some similar issues when building for release in a project similar to yours(Swift + Objective-C), in my case it was skipping a piece of code within a loop, but it was not skipping the loop itself. In order to solve this we changed at the Build Settings -> Apple LLVM 6.0 Code Generation -> Optimization Level the value of Debug to Fastest, Smallest [-Os], which was the same of Release and then we got the same bug on Debug. Then we tried to changing both to None [-O0] (Which is Debug default value) but it only made the bug disappear on Debug mode not in Release, so we had to workaround that code and change a little bit of the UI.

I would like to believe that it's something the compiler does in Release that can't be changed by us, so maybe it's an Xcode Bug.




回答2:


It's not a real solution, but as a workaround it worked to just not put the code inside a completion handler. Instead it is now part of a method (all context variables need to be accessible within that method of course) and I save the type of request I make.

When the request method from my above example runs and checks if it has a completion closure code to run I additionally added a check for the type and if it's the type where the bug happened then it simply calls that method where the completion code now is in.

This of course is very ugly but until Apple fixes this bug (I sent them a bug report with example code) I can't figure out any other solution. Maybe this workaround helps someone else as well. If my description is confusing just tell me and I will try to be clearer with some example code.




回答3:


The answer could be the previous one I gave to the question App crashes in Release build but not in debug.


Apple also describes a known issue. I describe it briefly in case someone is look for answer and the previous solution doesn't work.

Check your crashlog for errors like

Dyld Error Message:
  Library not loaded: @rpath/libswiftCore.dylib

or

[....] [deny-mmap] mapped file has no team identifier and is not a platform binary:
/private/var/mobile/Containers/Bundle/Application/5D8FB2F7-1083-4564-94B2-0CB7DC75C9D1/YourAppNameHere.app/Frameworks/libswiftCore.dylib

and follow apple guidance if you have similar crash output like the one above.

PS: You could check the log easily even under Window ->Device in XCode. click to the device and click view device logs.



来源:https://stackoverflow.com/questions/28153119/swift-behaves-differently-on-debug-and-release-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!