退出应用程序会导致错误“来自debugging器的消息:由于信号9而终止”
我正在编写一个基本的音乐播放器应用程序,但在处理应用程序状态转换时遇到一些问题。
我正在使用Swift 3和MPMusicPlayerController.systemMusicPlayer()
目标是这样的:
1)当用户点击主页button和应用程序进入BG(作品)保持音乐播放
2)停止播放器(myMP.stop())如果用户退出应用程序(有时工作,其他时间抛出错误)
我使用基于可能的行为的打印语句来追踪stream程,并得到这样的结果:
stream程2是我所期望的,但stream程1在应用程序closures时抛出一个错误 – 我期望在这里终止。
编辑:主要的问题是,当退出应用程序使用stream程1,“将终止”永远不会被调用 – 因此,“myMP.stop()”永远不会被调用,玩家继续播放应用程序退出后。
如果您在应用程序处于活动状态时单击Home(stream程1)或双击(Flow 2),则行为会有明显差异。
为什么我会从同样的行为中得到两个不同的回应?
编辑:最重要的是,如果它永远不会“终止”,我该如何停止MediaPlayer的stream1?
编辑:
以下是一些复制问题的示例代码:
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
“由于信号9而终止”消息意味着您的应用程序被SIGKILL信号终止。 操作系统每当您的应用程序被非自愿终止,无论是因为内存压力(还是其他一些与本次讨论无关的原因),或者用户通过双击主屏幕button并将其刷掉,都会发送该信号。
在你的情况下,用户显式地杀死你的应用程序,所以“完全由于信号9”消息是完全预期的。 如果您的应用程序是当前的前台应用程序,则您的applicationWillTerminate方法将被调用,如上面逻辑stream程概述(stream程2)所示。 如果您的应用程序不是当前的前台应用程序(stream程1),那么applicationWillTerminate
方法将不会被调用,如果您的应用程序处于挂起状态。 这是预期的行为。 还要注意“背景状态”和“暂停状态”之间的区别。 他们不是一回事 。
所以,如果我正确地理解了你的话,听起来问题是在你的应用程序被用户终止之后audio继续播放(stream程1)。 这意味着你在处理MPMusicPlayerController
,因为它应该自动处理这个状态转换。
确保你已经为你的应用程序设置了正确的UIBackgroundMode 。 设置错误的背景模式可能会导致应用程序不正常,因为操作系统只允许在后台进行某些操作,具体取决于您设置的背景模式。 设置错误的模式(或者尝试在您设置的模式下显式禁止的事情)会导致您的应用程序被暂停或终止。
确保你已经正确设置你的audio会话。
确保您正确响应音乐播放器通知 – 特别是,确保您正在调用beginGeneratingPlaybackNotifications
和endGeneratingPlaybackNotifications
,并且您正在正确处理这些通知。 检查你的通知处理程序,确保你没有在那里做任何愚蠢的事情。 确保您的控制器没有超出范围,否则在您调用endGeneratingPlaybackNotifications
之前获得释放。
如果你正确地做了所有的事情,一个MPMusicPlayerController
几乎pipe理自己,所以你不应该做任何特殊的事情,当你的应用程序去背景(除了设置正确的UIBackgroundMode
,当然)。 作为最后的手段,开始评论代码,直到你的应用程序只是一个准系统“打开audio文件和播放它”的应用程序,看看它是否正常退出。 如果是这样,你可以开始取消注释代码,直到它失败 – 然后你知道你的应用程序的哪一部分是造成问题,你可以从那里缩小它。
我有三个应用程序的背景任务。
<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 }
根据我们的需要。 它工作正常。