Ответ 1
Вы должны просто отключить ARC. Когда вы вводите backgroud, тогда, если вы его не используете, он освобождается. В Swift создайте AVAudioPlayer как объект Unmanaged<T>
.
У меня есть экземпляр AVAudioPlayer, который загружает звук в память с помощью audioPlayer.prepareToPlay()
, а затем после нескольких его воспроизведения. У меня есть проблема, что примерно через десять минут после ввода фона он течет из памяти, и я не готов. После этого я не могу снова запустить prepareToPlay()
. Как оставить этот предустановленный звук в памяти на длительный срок? Я готовлю звук для воспроизведения в методе applicationDidFinishLaunchingWithOptions
:
let dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(dispatchQueue, {[weak self] in
var audioSessionError: NSError?
let audioSession = AVAudioSession.sharedInstance()
NSNotificationCenter.defaultCenter().addObserver(self!, selector: "handleInterruption:", name: AVAudioSessionInterruptionNotification, object: nil)
audioSession.setActive(true, error: nil)
if (audioSession.setCategory(AVAudioSessionCategoryPlayback, error: &audioSessionError)) {
println("Successfully set the audio session")
} else {
println("Could not set the audio session")
}
let filePath = NSBundle.mainBundle().pathForResource("sound", ofType:"mp3")
let fileData = NSData(contentsOfFile: filePath!, options: .DataReadingMappedIfSafe, error: nil)
var error:NSError?
self!.audioPlayer = AVAudioPlayer(data: fileData, error: &error)
self!.audioPlayer?.numberOfLoops = -1
self!.audioPlayer?.delegate = self
if (self?.audioPlayer?.prepareToPlay() != false) {
println("Successfully prepared for playing")
} else {
println("Failed to prepare for playing")
}
})
Затем в didReceiveRemoteNotification
я пытаюсь воспроизвести его в фоновом режиме: self.audioPlayer?.play()
, он возвращает true
. Наверное, это работает, но примерно через 10-20 минут это не сработает. И обратите внимание, что .play()
теперь возвращает false
.
Есть ли смысл отключить ARC (автоматический подсчет ссылок) для освобождения и dealloc audioPlayer
вручную?
Возможно, мне нужно использовать API более низкого уровня, например OpenAL
? Однако я не буду использовать его, поскольку он устарел в iOS 9 и позже мне нужно будет переписать его без OpenAL
.
Есть идеи? Может быть, мне нужно использовать Audio Units
с RemoteIO
? Если это сработает, укажите несколько примеров.
Возможно, существуют сторонние структуры, такие как ObjectAL
- простая реализация OpenAL
. Как я знаю, он доступен в iOS 9.
Эти методы - только мои предположения. Но главный вопрос остается тем же: Будут ли эти методы работать из фона?
Вы должны просто отключить ARC. Когда вы вводите backgroud, тогда, если вы его не используете, он освобождается. В Swift создайте AVAudioPlayer как объект Unmanaged<T>
.