diff --git a/cocos/audio/AudioEngine.cpp b/cocos/audio/AudioEngine.cpp index 0f822147be..945ebf1e21 100644 --- a/cocos/audio/AudioEngine.cpp +++ b/cocos/audio/AudioEngine.cpp @@ -364,15 +364,23 @@ void AudioEngine::stopAll() void AudioEngine::uncache(const std::string &filePath) { - if(_audioPathIDMap.find(filePath) != _audioPathIDMap.end()){ - auto itEnd = _audioPathIDMap[filePath].end(); - for (auto it = _audioPathIDMap[filePath].begin() ; it != itEnd; ++it) { - auto audioID = *it; + auto audioIDsIter = _audioPathIDMap.find(filePath); + if (audioIDsIter != _audioPathIDMap.end()) + { + //@Note: For safely iterating elements from the audioID list, we need to copy the list + // since 'AudioEngine::remove' may be invoked in '_audioEngineImpl->stop' synchronously. + // If this happens, it will break the iteration, and crash will appear on some devices. + std::list copiedIDs(audioIDsIter->second); + + for (int audioID : copiedIDs) + { _audioEngineImpl->stop(audioID); auto itInfo = _audioIDInfoMap.find(audioID); - if (itInfo != _audioIDInfoMap.end()){ - if (itInfo->second.profileHelper) { + if (itInfo != _audioIDInfoMap.end()) + { + if (itInfo->second.profileHelper) + { itInfo->second.profileHelper->audioIDs.remove(audioID); } _audioIDInfoMap.erase(audioID); @@ -381,7 +389,8 @@ void AudioEngine::uncache(const std::string &filePath) _audioPathIDMap.erase(filePath); } - if (_audioEngineImpl){ + if (_audioEngineImpl) + { _audioEngineImpl->uncache(filePath); } }