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.
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.
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.
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