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

2024-03-06

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

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

目标是这样的:

1)当用户点击主页按钮并且应用程序进入背景时保持音乐播放(有效)

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

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

Flow 2 是我所期望的,但 Flow 1 抛出错误 当应用程序关闭时 - 我希望这里“将终止”。

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

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

为什么我得到两个不同的回应应该相同的动作?

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

EDIT:

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

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 http://www.NextCoInc.com/public/junkplayer.zip


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

在您的情况下,用户明确终止您的应用程序,因此“由于信号 9 而终止”消息完全是预料之中的。如果您的应用程序是当前的前台应用程序,您的应用程序将终止 https://developer.apple.com/reference/uikit/uiapplicationdelegate/1623111-applicationwillterminate方法将被调用,如上面的逻辑流程概述(流程 2)所示。如果您的应用程序不是当前的前台应用程序(流程 1),您的applicationWillTerminate如果您的应用程序处于挂起状态,则不会调用该方法。这是预期的行为。另请注意“后台状态”和“挂起状态”之间的区别。它们不是同一件事 https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html.

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

确保您已设置正确UI背景模式 https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW22为您的应用程序。设置错误的后台模式可能会导致应用程序行为异常,因为操作系统仅允许在后台执行某些操作,具体取决于您设置的后台模式。设置错误的模式(或尝试执行您设置的模式中明确禁止的操作)将导致您的应用程序被暂停或终止。

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

确保您正确回应音乐播放器通知 https://developer.apple.com/reference/mediaplayer/mpmusicplayercontroller- 特别是,请确保您正在打电话beginGeneratingPlaybackNotifications and endGeneratingPlaybackNotifications适当地,并且您正在正确处理这些通知。检查您的通知处理程序,确保您没有在其中做任何愚蠢的事情。确保您的控制器在调用之前不会超出范围或以其他方式被释放endGeneratingPlaybackNotifications.

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐