3 Replies
      Latest reply: Dec 3, 2016 6:30 AM by eskimo RSS
      rnikander Level 1 Level 1 (10 points)

        Hi,

         

        I have an app that used to work, but I just tried to update it now it doesn't work in Relase builds (but it's fine in Debug builds). It turns out that when the Swift compiler optimization level is at "Fast, Whole Module Optimization" (the default for Release) my app fails to play sound with AVSpeechSynthesizer.  Is this a bug is Swift? It should behave the same, correct? Or is there something I can look for in my code that might cause a change in behavior with the optimization level?

         

        Rob

        • Re: Optimization level breaks my app
          KMT Level 8 Level 8 (6,915 points)

          Perhaps if you talked a bit about which version Xcode/Swift etc. your app supports.

            • Re: Optimization level breaks my app
              rnikander Level 1 Level 1 (10 points)

              All the latest: Xcode 8.1, Swift 3.

               

              After doing some research I think it's a compiler bug -- behavior shouldn't change just because you change optimization levels. I removed whole-module optimization, the app works, I resubmitted it (after rejection) and it was accepted. I just don't have time to debug Apple's products for them unless they want to pay me.  But clearly something is wrong with whole-module optimization.

               

              Rob

                • Re: Optimization level breaks my app
                  eskimo Apple Staff Apple Staff (6,055 points)

                  … behavior shouldn't change just because you change optimization levels …

                  Alas, that’s only true if all the code in your process follows all of the rules to the letter.  There are plenty of places where incorrect code, both your code and framework code, can cause bugs that only show up in optimised builds.  Swift’s emphasis on safety reduces the likelihood of this, but it does not eliminate it entirely.

                  For example, consider code like this:

                  func playSound() {
                      let channel = makeSoundChannel()
                      channel.playSomethingAsync()
                  }
                  

                  In a non-optimised build the object returned by makeSoundChannel() might get put in the autorelease pool, which defers its deallocation until you return to the event loop.  OTOH, the optimiser might shuffle the code around so that the deallocation happens immediately on return from playSound().  Neither of these is incorrect in and of itself.  However, if deallocating channel cancels the async request to play sound, you get a sound in your non-optimised build and no sound is your release build.

                  This is just one of many potential issues that can show up in optimised builds.  To understand what’s causing your issue, you’re going to have to dig deeper.  It may well turn out to be a compiler bug, but in my experience those are few and far between, even when dealing with a relatively immature compiler.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"