退出应用程序会导致错误“来自调试器的消息:由于信号 9 而终止”

Posted

技术标签:

【中文标题】退出应用程序会导致错误“来自调试器的消息:由于信号 9 而终止”【英文标题】:Quitting app causes error "Message from debugger: Terminated due to signal 9" 【发布时间】:2017-07-08 23:34:13 【问题描述】:

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

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

目标是这样的:

1) 当用户点击 Home 按钮并且应用进入 bg 时,继续播放音乐(有效)

2) 如果用户退出应用程序,则停止播放器( myMP.stop() )(有时有效,其他时候抛出错误)

我根据可能的操作使用打印语句跟踪流程并得到以下信息:

流程 2 是我所期望的,但流程 1 会引发错误 当应用程序关闭时 - 我希望在这里“将终止”。

编辑:主要问题是当使用流程 1 退出应用程序时,永远不会调用“将终止” - 因此永远不会调用“myMP.stop()”,并且播放器会在应用程序退出后继续播放。

如果您在应用程序处于活动状态时单击主页一次(流程 1)或两次(流程 2),行为会有明显差异。

为什么我会从应该相同的操作中得到两个不同的响应?

编辑: 最重要的是,如果 Flow 1 的 MediaPlayer 永远不会“将终止”,我该如何停止它?

编辑:

这里是一些复制问题的示例代码:

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

【问题讨论】:

你能重新上传所有代码吗?我试着修复它。谢谢 @JosePoseS 我修复了上面的链接——你现在应该可以下载了。正如我在下面给 Jeff 的 cmets 中提到的,更改为 applicationMusicPlayer 可以解决主要问题,但会导致其他问题...... 就我而言,当我从 xcode 在设备上运行应用程序时收到此消息,同时我尝试在我的设备上从 appstore 安装相同的应用程序。 【参考方案1】:

“因信号 9 终止”消息仅表示您的应用已被 SIGKILL 信号终止。每当您的应用程序非自愿终止时,操作系统都会发送该信号,无论是由于内存压力(或与本讨论无关的其他几个原因),还是用户通过双击主页按钮并将其滑开来明确终止您的应用程序。

在您的情况下,用户明确地终止了您的应用程序,因此完全可以预料到“由于信号 9 而终止”消息。如果您的应用程序是当前前台应用程序,您的 applicationWillTerminate 方法将被调用,如上面的逻辑流程大纲所示(流程 2)。如果您的应用程序不是当前前台应用程序(流程 1),如果您的应用程序处于挂起状态,您的 applicationWillTerminate 方法将不会被调用。这是预期的行为。还要注意“背景状态”和“暂停状态”之间的区别。 They are not the same thing.

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

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

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

确保您正确响应music player notifications - 特别是,确保您正确调用beginGeneratingPlaybackNotificationsendGeneratingPlaybackNotifications,并且正确处理这些通知。检查您的通知处理程序以确保您没有在其中做任何愚蠢的事情。在您调用 endGeneratingPlaybackNotifications 之前,请确保您的控制器不会超出范围或以其他方式被释放。

如果您已正确完成其他所有操作,MPMusicPlayerController 几乎可以自行管理,因此当您的应用程序进入后台时,您无需执行任何特殊操作即可使其正常工作(除了设置正确的 @987654332 @, 当然)。作为最后的手段,开始注释代码,直到您的应用程序只是一个准系统的“打开音频文件并播放它”应用程序,然后查看它是否正确退出。如果是这样,您可以开始逐段取消注释代码,直到它失败 - 然后您知道您的应用程序的哪个部分导致了问题,您可以从那里缩小范围。

【讨论】:

我已经阅读了您的帖子和链接(谢谢)我已经创建了最简单的播放器版本,但我仍然遇到同样的问题。我已将其设置为后台音频应用程序 - 没有变化。我已经在不同的地方声明了我的 MediaPlayer 的实例——没有变化。我如何向您提供此项目的副本以查看您是否可以解决问题? 发布您设置MPMusicPlayerController 对象的代码部分。确保您在 主线程 上管理此对象(请参阅:developer.apple.com/reference/mediaplayer/…)。 另外,您使用的是Application Music Player,还是System Music Player?根据我之前评论中的链接,如果您在创建对象时未指定它,您将获得系统音乐播放器 - 也许这就是为什么当您的应用程序终止时它不会停止播放? 我稍后会发布我的代码 - 但是,我可以告诉你我正在使用系统音乐播放器 - 原因是我希望它在后台继续播放 -与 Apple Music 播放器相同。否则,点击 Home(等)会暂停播放器。 好的,我想我已经解决了。我一直在使用系统音乐播放器,错误地认为它是后台播放所必需的。在阅读和测试之后,我已经切换到应用程序播放器并在 info.plist 中设置了后台功能,它似乎工作正常。另外,无论我如何退出应用程序,它都会退出/停止播放。我将进行更多测试,但我相信您引导我找到了正确的解决方案 - 一旦我的测试完成,我将很乐意奖励积分!【参考方案2】:

Settings 应用程序对 CameraPhoto 使用等应用程序权限的更改可能会导致此信号崩溃(硬刷新)。

您可以在以下链接中找到相关行为:

App killed by SIGKILL when changing privacy settings

【讨论】:

为什么会这样? I Thing 如果用户更改某些内容,Apple 将硬刷新,以便应用程序可以从 AppDelegate 启动作为新的开始。 这是我的情况,我正在测试我的照片应用程序以了解如何处理手动设置更改,并且有时会收到此崩溃和错误消息,很高兴知道这是系统本身如何处理我的应用程序,我将继续测试我的应用程序,我们知道问题可能出在椅子和电脑屏幕之间 lmao【参考方案3】:

我正在为应用程序执行三个后台任务。

<key>UIBackgroundModes</key>
<array>
    <string>bluetooth-central</string>
    <string>location</string>
    <string>remote-notification</string>
</array> 

Message from debugger: Terminated due to signal 9 当应用程序在后台运行时会出现此消息,并且它消耗的内存超出了 iPhone 操作系统为后台运行的应用程序分配的内存。

在我的情况下,我不断更新用户的位置并将用户的位置 api 执行到服务器。它消耗了大量的内存。由于这个原因,操作系统杀死了应用程序。

由于操作系统的内存压力,我们收到此消息并在后台终止了应用程序。

我优化了代码,每当我们需要更新用户的位置时,我们只需将位置 api 发送到服务器。 我也是enable \ disable国旗allowsBackgroundLocationUpdates

if #available(ios 9.0, *) 
   coreLocationManager.allowsBackgroundLocationUpdates = false

根据我们的需要。 效果很好。

【讨论】:

“运行良好”是什么意思?这是否意味着应用程序留在内存中并且不再“因信号 9 而终止”?

以上是关于退出应用程序会导致错误“来自调试器的消息:由于信号 9 而终止”的主要内容,如果未能解决你的问题,请参考以下文章

iOS 使用新的隐私设置强制重启应用

为啥 CoUninitialize 在退出时会导致错误?

为啥程序退出时全局或静态对象会导致崩溃?

使用 VBA 退出 Excel 会导致运行时错误 424

在 Delphi 6 中加载特定帧会导致它立即退出

Xcode 9.2升级导致此错误:“命令/ bin / sh失败,退出代码为1”