退出应用程序会导致错误“来自调试器的消息:由于信号9而终止” [英] Quitting app causes error "Message from debugger: Terminated due to signal 9"

查看:5108
本文介绍了退出应用程序会导致错误“来自调试器的消息:由于信号9而终止”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个基本的音乐播放器应用程序但在处理应用程序状态转换时遇到一些问题。

I'm writing a basic music player app but having some problems when it comes to handling the app state transitions.

我正在使用Swift 3和MPMusicPlayerController。 systemMusicPlayer()

I'm using Swift 3 and MPMusicPlayerController.systemMusicPlayer()

目标是:

1)当用户点击主页按钮时保持音乐播放app进入bg(工作)

1) Keep music playing when user taps the Home button and app enters bg (works)

2)如果退出应用程序的用户停止播放器(myMP.stop())(有时工作,有时会抛出错误)

2) Stop the player ( myMP.stop() ) if the user the quits the app (works sometimes, throws error other times)

我根据可能的操作使用print语句跟踪流程并得到:

I traced the flows using print statements based on possible actions and got this:

流量2是我所期望的,但当应用程序关闭时,流量1会抛出错误
- 我预计会终止这里。

Flow 2 is what I would expect, but Flow 1 throws an error when the app is closed - I would expect "will terminate" here.

编辑:主要问题是当使用流程1退出应用程序时,将终止永远不会被调用 - 那里从来没有调用myMP.stop()并且玩家在应用程序退出后继续播放。

The main issue is that when exiting the app using Flow 1, "will terminate" is never called - therefore "myMP.stop()" is never called and the player continues to play after the app has exited.

如果单击Home,则行为会有明显差异应用程序处于活动状态时(流程1)或双倍(流程2)。

There is a distinct difference in behavior if you click Home once (Flow 1) or double (Flow 2) while the app is active.

为什么我会从应该获得两个不同的响应同样的行动?

Why do I get two different responses from what should be the same actions?

编辑:
最重要的是,如果流量1永远不会终止,我如何停止MediaPlayer?

Most importantly, how do I stop the MediaPlayer for Flow 1 if it never gets to "will terminate" ?

编辑:

以下是一些复制问题的示例代码:

Here is some sample code that replicates the issue:

AppDelegate.swift

AppDelegate.swift

//
//  AppDelegate.swift
//  Jumbo Player
//

import UIKit
//import MediaPlayer

//doesn't matter where this is declared - here or in ViewController - same results
//let myMP:MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer()

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
        print("applicationWillResignActive")
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
        print("applicationDidEnterBackground")
    }

    func applicationDidReceiveMemoryWarning(_ application: UIApplication) {
        print("applicationDidReceiveMemoryWarning")
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
        print("applicationWillEnterForeground")
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        print("applicationDidBecomeActive")
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
        print("applicationWillTerminate")
        myMP.stop();
    }
}

ViewController.swift

ViewController.swift

//
//  ViewController.swift
//  junkplayer
//

import UIKit
import MediaPlayer

let myMP:MPMusicPlayerController = MPMusicPlayerController.systemMusicPlayer()

class ViewController: UIViewController {

    @IBOutlet weak var xxx: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let qrySongs = MPMediaQuery.songs()
        myMP.setQueue(with: qrySongs)

    }

    @IBAction func playbut(_ sender: UIButton) {
        myMP.play()
    }
}

在此下载项目: www.NextCoInc.com/public/junkplayer.zip

推荐答案

因信号9而终止消息只表示您的应用程序被SIGKILL信号终止。操作系统会在您的应用程序被非自愿终止时发送该信号,无论是因为内存压力(或与此讨论无关的其他几个原因),还是用户通过双击主页按钮并将其轻扫而明确查杀您的应用程序。

The "terminated due to signal 9" message just means your app was terminated by a SIGKILL signal. The OS sends that signal whenever your app is terminated involuntarily, whether it's because of memory pressure (or several other reasons not relevant to this discussion), or the user explicitly killing your app by double tapping the Home button and swiping it away.

在您的情况下,用户明确地终止您的应用程序,因此完全需要因信号终止9消息。如果您的应用程序是当前的前台应用程序,则会调用您的 applicationWillTerminate 方法,如上面的逻辑流程大纲(流程2)所示。如果您的应用程序不是当前的前台应用程序(流程1),那么如果您的应用程序处于挂起状态,则不会调用 applicationWillTerminate 方法。这是预期的行为。还要注意背景状态和暂停状态之间的区别。 它们不是一回事

In your case, the user is explicitly killing your application, so the "Terminated due to signal 9" message is completely expected. If your application is the current foreground application, your applicationWillTerminate method will get called, as shown in your logic flow outline above (Flow 2). If your application is NOT the current foreground application (Flow 1), your applicationWillTerminate method will NOT get called if your application is in a suspended state. This is expected behavior. Also note the distinction between "background state" and "suspended state". They are not the same thing.

因此,如果我理解正确,听起来问题是在用户终止您的应用程序后,音频会继续播放(流程1)。这意味着你在处理 MPMusicPlayerController 时做错了,因为它应该自动处理该状态转换。

So if I'm understanding you correctly, it sounds like the problem is that the audio continues playing after your application is terminated by the user (Flow 1). That means you are doing something wrong in your handling of the MPMusicPlayerController, because it should handle that state transition automatically.

确保您设置了正确的 UIBackgroundMode 。设置错误的后台模式可能会导致应用程序出现异常,因为操作系统仅允许在后台运行某些操作,具体取决于您设置的背景模式。设置错误的模式(或尝试执行您设置的模式中明确禁止的操作)将导致您的应用被暂停或终止。

Make sure you've set the correct UIBackgroundMode for your app. Setting the wrong background mode can cause your application to misbehave because the OS only allows certain operations while in background, depending on what background mode you've set. Setting the wrong mode (or trying to do things that are explicitly disallowed in the mode you've set) will cause your app to be suspended or terminated.

确保您已正确设置音频会话。

Make sure you've set up your audio session correctly.

确保您正确回复音乐播放器通知 - 特别是,请确保您正在调用 beginGeneratingPlaybackNotifications endGeneratingPlaybackNotifications 恰当,并且您正确处理这些通知。检查您的通知处理程序,以确保您没有在那里做任何愚蠢的事情。在调用 endGeneratingPlaybackNotifications 之前,请确保您的控制器不会超出范围或以其他方式发布。

Make sure you are responding correctly to the music player notifications - in particular, make sure you're calling beginGeneratingPlaybackNotifications and endGeneratingPlaybackNotifications appropriately, and that you are handling those notifications correctly. Check your notification handlers to make sure you aren't doing anything silly in there. Make sure your controller doesn't go out of scope or otherwise get released before you've called endGeneratingPlaybackNotifications.

如果你已经正确完成了所有其他事情,那么 MPMusicPlayerController 几乎可以管理自己,所以当你的应用程序进入后台时你不必做任何特别的工作(除了设置正确的 UIBackgroundMode ,当然)。作为最后的手段,开始评论代码,直到您的应用程序只是一个准确的打开音频文件并播放它应用程序,然后查看它是否正常退出。如果是这样,您可以逐个取消注释代码直到它失败 - 然后您知道应用程序的哪个部分导致了问题,您可以从那里缩小它。

If you've done everything else correctly, an MPMusicPlayerController pretty much manages itself, so you shouldn't have to do anything special to make it work when your app goes to the background (aside from setting the correct UIBackgroundMode, of course). As a last resort, start commenting out code until your app is just a barebones "open-an-audio-file-and-play-it" application, and see if it exits properly then. If it does, you can start uncommenting code piece-by-piece until it fails - then you know what part of your app is causing the problem and you can narrow it down from there.

这篇关于退出应用程序会导致错误“来自调试器的消息:由于信号9而终止”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆