34

As I said in the title, I am writing an app for iPhone which runs perfectly in debug mode but when I build it as release and install it via TestFlight, it crashes. Due to the crash log it might have to do something with this lines:

let path = NSBundle.mainBundle().pathForResource("PrinterList", ofType: "plist")
if path != nil {
    let printerDic = NSDictionary(contentsOfFile: path!)
    let printerList = NSArray(array: printerDic.allKeys)
    printerNames = printerList as [String]
}

I am using an framework from Brother to print without AirPrint, but I think thats not the problem because the app crashes before doing something with the framework. It crashes only in this ViewController where I execute these lines. I need the framework only in this ViewController as well.

Ben
  • 3,455
  • 3
  • 26
  • 31
  • 9
    If you turn off Swift compiler optimisations for the release build, and try it again, do you still get the crash? (In build settings, under Swift Compiler/Code Generation) – Matt Gibson Sep 02 '14 at 19:13
  • If I do this I can't install it via TestFlight: 'Invalid Profile: distribution build entitlements must have get-task-allow set to false.' But I try with iTunes.. EDIT: Does not work with iTunes and Xcode to install.. – Ben Sep 02 '14 at 19:18
  • YES! It worked! Thank you so much. Please write your comment as an answer so that I can mark it as the right answer – Ben Sep 02 '14 at 19:29
  • Well, bear in mind that that may not be the real answer—it may be that there's some kind of bug in Swift optimisation, which isn't that unlikely in a beta, but there's also a chance that the optimised build is showing up a bug in your code that's not so apparent in the non-optimised version. That can happen in any language... Have you tried an optimised release with Xcode 6 beta 7 yet? That was just released; it's probably worth a try... – Matt Gibson Sep 02 '14 at 21:56
  • No, it was too late yesterday here in Germany. But I will give it a try in a few hours :) – Ben Sep 03 '14 at 05:01
  • Using Beta 7 doesn't change it, when compiling with Fastest optimisations in release.. – Ben Sep 03 '14 at 05:14
  • 1
    My app was crashing and it seemed to be a possible NSArray issue just like your code suggests. The app would run fine then after changing the array (which is loaded on startup) the app would crash... Rebuilding in debug would then open the same saved array. Thanks for the question and fix! – werm098 Mar 20 '15 at 23:26

4 Answers4

39

There are many reasons that an app might crash in release mode but not in debug mode (e.g. memory allocation differences showing up a bug that actually exists in both builds.) They can take a lot of work to track down, even with a non-beta compiler/language.

You say that the problem goes away if you do as I suggested and build for release with optimisations turned off. Given that the Swift compiler is still in beta and definitely still has the occasional problem—I've seen the compiler simply crash when building optimised builds—this may actually be an optimiser bug.

For now, therefore, I'd defer looking into it. Release without optimisations until we get a full release version of the compiler. Then, turn optimisations back on and see if you still have the problem. If you do, that's the time to start spending your energy trying to figure out if it's a compiler bug or a bug in your own code.

Matt Gibson
  • 37,886
  • 9
  • 99
  • 128
  • 1
    I was in the same way, app just working fine on debug mode, but using test flight it crash. But now I followed your advice and it is working fine. Thanks a lot! "If you turn off Swift compiler optimisations for the release build, and try it again, do you still get the crash? (In build settings, under Swift Compiler/Code Generation)" – Bruno Morais Feb 20 '15 at 12:41
  • Thank you for this fix! Swift 1.2 still has this issue. – werm098 Mar 20 '15 at 23:24
  • 1
    Bug still there... Thanks a ton Matt, you saved my day! First time in 20 years of coding that it is due to the compiler... – beetree Apr 16 '15 at 18:19
  • My Release version crashed due to the `split` function. See my answer here: http://stackoverflow.com/questions/29107277/swift-release-build-crashes-unless-i-turn-off-optimization/32361548#32361548 – Mike Taverne Sep 02 '15 at 21:08
  • Just wanted to check if anyone found similar app crash issues with latest iOS release version 9.3.1 too? We found this issue in iOS9.3 with optimization level set to Maximum, when changed to NONE, app worked just fine. Please let us know if anyone has any additional inputs in this regard. Thanks in advance ! – Birender Singh Apr 08 '16 at 15:11
  • App crash issue was due to memory leak. Optimization solution didn't work. for me. Not sure why this doesn't happen in debugging mode. – Alex Jin Jun 09 '16 at 03:40
  • This dumb feature stole my 2-3 weeks, also it was responsible of other 2-3 stupid bugs as well. Thank you. – ACAkgul Dec 03 '18 at 08:52
9

I've had the same problem. I finally fixed it by turning on whole module optimization. Combined with correct implementations of access control this should fix your crash.

Whole module optimization according to Apple:

Use Whole Module Optimization to infer final on internal declarations. Declarations with internal access (the default if nothing is declared) are only visible within the module where they are declared. Because Swift normally compiles the files that make up a module separately, the compiler cannot ascertain whether or not an internal declaration is overridden in a different file. However, if Whole Module Optimization is enabled, all of the module is compiled together at the same time. This allows the compiler to make inferences about the entire module together and infer final on declarations with internal if there are no visible overrides.

You can enable this in your project settings:

Whole Module Optimization

But be aware this option optimizes all of the files in a target together and enables better performance at the cost of increased compile time.

Antoine
  • 23,526
  • 11
  • 88
  • 94
  • Thank you, you saved my weekend. – kubilay Mar 03 '17 at 15:01
  • 1
    I have crash `outlined destroy of MyStruct` which is able to reproduce only when `Compilation Mode = Whole module` and `Optimization Level = Optimize for Speed [-O]` in the same time. If I change one of these options then crash disappears, but it appears that both are recommended for Release build. I have no idea what is wrong and I don't know how to catch it as it occurs only in Release builds. – Ariel Bogdziewicz Aug 01 '19 at 09:37
6

To catch the crash test the with the Optimization Level set to Fastest, Smallest [-Os] in Debug mode to more closely simulate the code that will be generated & running on the user’s device.

You can set it in build settings, under Swift Compiler/Code Generation

Sakshi Singla
  • 531
  • 6
  • 5
1

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.

flatronka
  • 1,061
  • 25
  • 51