iOS 应用在调试与发布方案中的行为不同

iOS app behaves differently with debug vs release scheme

在我的应用程序中,我同时进行了三个 运行 互联网操作。他们不相互依赖,所以我 运行 他们每个人都在后台线程中。他们每个人都需要完成,但在我的应用程序可以移动到完成处理程序之前。

启动三个方法中的每一个的方法接收作为参数的块代码,充当完成处理程序。此方法还有一个名为 internetOperationsRemaining 的局部变量,我在开始三个 Internet 操作中的每一个之前将其设置为 3。

当每个互联网操作完成后,我减少主线程上的 internetOperationsRemaining。当它们全部完成时,这会导致 internetOperationsRemaining == 0。

为了监听这种情况,我 运行 在另一个后台线程上进行了一个紧密循环,该线程只是在自身循环等待 internetOperationsRemaining 等于 0。一旦发生这种情况,我将调用作为参数传入的完成处理程序如前所述。

    //Spawn a background thread and loop in it until
    //allInternetOperationComplete == true.

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        while(internetOperationsRemaining > 0)
        {
            //Just spins in here on a background thread waiting 
            //on the internet to finish.
        }

        //Now that internetOperationsRemaining == 0, kill the NSURL session 
        //and call the completion handler on the main thread.

        dispatch_async(dispatch_get_main_queue(), ^{
            [session finishTasksAndInvalidate];
            completionHandler();   
        });
  });

我看到的奇怪行为是,如果我在方案中设置了调试,应用程序 运行 是完美的,如果我选择了发布,则不会。它永远不会跳出 while 循环。

如果我在 while 循环中插入一些简单的代码来稍微减慢速度,它在调试和发布时都能正常工作。

    while(internetOperationsRemaining > 0)
    {
        //Just spins in here on a background thread waiting 
        //on the internet to finish.
        int i=0;
        ++i;
    }

我无法解释这种行为。紧密循环在后台线程上进行,因此该应用程序会像预期的那样保持对用户输入的响应。我意识到发布方案引入了优化,但我很惊讶它实际上改变了应用程序的行为。

如果没有 运行 代码来检查,我认为正在进行的是某种编译器优化,它只出现在发布代码中。

我认为真正的问题更多在于设计。使用计数器和纺纱不是很好。我建议研究使用 NSOperations。您可以设置操作的层次结构,以便您的完成操作依赖于其他三个。继续阅读有关使用操作、并发队列和依赖项的内容,您会明白的。