MusicSequenceFileLoad Returns -1 在 iOS10 (AudioToolbox/MusicPlayer)
MusicSequenceFileLoad Returns -1 on iOS10 (AudioToolbox/MusicPlayer)
2016 年 9 月 10 日更新: 我在 2016 年 9 月 22 日与 Apple 一起打开了 Radar #28425770 以解决以下缺陷,他们刚刚将其标记为重复(来自 Radar #28327056),因此这似乎是 iOS10.
中的一个已知错误
我在调用 AudioToolbox / MusicPlayer API 方法 "MusicSequenceFileLoad()" 将 MIDI 文件的内容(来自给定 URL)加载到音乐序列时遇到错误iOS10 iPad Pro(wifi 型号),非常感谢社区在调试方面提供的一些帮助。
到目前为止我能够进行的研究/观察:
此代码已在 iOS7、8 和 9 上正常运行 2 年以上,并且在 iOS 10 模拟器上运行也没有问题,但是 returns 仅在 iOS 10.0.1 iPad Pro Wifi 型号上出现错误。
我无法在其他设备上重新创建,也请了一些朋友也尝试一下。测试无问题的设备:iPhone 6+、iPad Mini 4th Gen、iPad Pro Cellular。
第一次显示使用此 MIDI 文件的 VC 时,所有处理运行都没有任何问题。这是 VC 第二次(有时是第三次)在应用程序崩溃的地方加载。该问题可以在 100% 的时间内始终如一地重现。
检查调用此函数的 OSStatus 结果代码只是 returns 值为 -1,并不表示失败的原因。
在 Xcode 中进行调试时,没有可用的崩溃报告、异常信息或调用堆栈。
对内存管理问题(分配、泄漏、僵尸)的分析,没有显示任何与崩溃相关的信息;打开 Zombie Objects 选项不会显示任何 Zombie Objects。
分析应用程序未发现任何未释放内存的区域。
将对象更改为静态没有任何影响,因此这似乎与内存无关。
如果有人对我调试此问题的其他方法有任何建议,将不胜感激。我最初认为它可能与内存管理有关,但是从我所看到的情况来看,我正在适当地处理内存(对应用程序使用 ARC 并根据需要释放 C-API 对象)并且分析没有发现任何我可以解决的问题看。
代码示例:
@property (readwrite, nonatomic) MusicPlayer midiMusicPlayer;
@property (readwrite, atomic) MusicSequence masterMidiMusicSequence;
- (void)initializeMusicPlayerAndMasterSequenceWithFile:(NSString *)midiFilename
{
CheckError(NewMusicPlayer(&_midiMusicPlayer), "NewMusicPlayer: _midiMusicPlayer");
CheckError(NewMusicSequence(&_masterMidiMusicSequence), "NewMusicSequence: _masterMidiMusicSequence");
NSString *midiFilePath = [NSBundle pathForResource:midiFilename
ofType:@"mid"
checkDocumentsDirectory:YES];
NSURL *midiFileURL = [NSURL fileURLWithPath:midiFilePath];
// Crash is encountered on the following line:
CheckError(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
}
您是否尝试将 NSAppleMusicUsageDescription
添加到您的 Info.plist
?
Starting in iOS 10, your Info.plist file must include a purpose string, for display in the permission alert, for each such item. If your app attempts to access a protected item without you having provided a corresponding purpose string, your app exits.
有关详细信息,请参阅 App Programming Guide for iOS。
我通过 Core Audio Mailing List 收到了 Apple 工程师的一些指导,并在 iOS10 中成功实施了针对此问题建议的解决方法。
通过在调用失败后将 "errno" 值更新为 0,后续对 'MusicSequenceFileLoad' 的调用将生成成功的响应。因此,我修改了我的代码如下:
OSStatus statusOfInitialAttempt = CheckError(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
if (statusOfInitialAttempt == -1) {
errno = 0;
OSStatus statusOfSecondAttempt = CheckErrorAndReturnOnFailure(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
if (statusOfSecondAttempt == -1) {
// Handle error case
}
}
... 其中 CheckError() 函数只是根据已知的 OSStatus 代码检查 OSStatus return 值,类似于 this one on GitHub (originally created by Chris Adamson from his blog post / presentation "Core Audio Cranks It Up").
我了解到,根据核心音频邮件列表上发布的内容,此问题有望在未来的 iOS 更新中得到解决。
2016 年 9 月 10 日更新: 我在 2016 年 9 月 22 日与 Apple 一起打开了 Radar #28425770 以解决以下缺陷,他们刚刚将其标记为重复(来自 Radar #28327056),因此这似乎是 iOS10.
中的一个已知错误我在调用 AudioToolbox / MusicPlayer API 方法 "MusicSequenceFileLoad()" 将 MIDI 文件的内容(来自给定 URL)加载到音乐序列时遇到错误iOS10 iPad Pro(wifi 型号),非常感谢社区在调试方面提供的一些帮助。
到目前为止我能够进行的研究/观察:
此代码已在 iOS7、8 和 9 上正常运行 2 年以上,并且在 iOS 10 模拟器上运行也没有问题,但是 returns 仅在 iOS 10.0.1 iPad Pro Wifi 型号上出现错误。
我无法在其他设备上重新创建,也请了一些朋友也尝试一下。测试无问题的设备:iPhone 6+、iPad Mini 4th Gen、iPad Pro Cellular。
第一次显示使用此 MIDI 文件的 VC 时,所有处理运行都没有任何问题。这是 VC 第二次(有时是第三次)在应用程序崩溃的地方加载。该问题可以在 100% 的时间内始终如一地重现。
检查调用此函数的 OSStatus 结果代码只是 returns 值为 -1,并不表示失败的原因。
在 Xcode 中进行调试时,没有可用的崩溃报告、异常信息或调用堆栈。
对内存管理问题(分配、泄漏、僵尸)的分析,没有显示任何与崩溃相关的信息;打开 Zombie Objects 选项不会显示任何 Zombie Objects。
分析应用程序未发现任何未释放内存的区域。
将对象更改为静态没有任何影响,因此这似乎与内存无关。
如果有人对我调试此问题的其他方法有任何建议,将不胜感激。我最初认为它可能与内存管理有关,但是从我所看到的情况来看,我正在适当地处理内存(对应用程序使用 ARC 并根据需要释放 C-API 对象)并且分析没有发现任何我可以解决的问题看。
代码示例:
@property (readwrite, nonatomic) MusicPlayer midiMusicPlayer;
@property (readwrite, atomic) MusicSequence masterMidiMusicSequence;
- (void)initializeMusicPlayerAndMasterSequenceWithFile:(NSString *)midiFilename
{
CheckError(NewMusicPlayer(&_midiMusicPlayer), "NewMusicPlayer: _midiMusicPlayer");
CheckError(NewMusicSequence(&_masterMidiMusicSequence), "NewMusicSequence: _masterMidiMusicSequence");
NSString *midiFilePath = [NSBundle pathForResource:midiFilename
ofType:@"mid"
checkDocumentsDirectory:YES];
NSURL *midiFileURL = [NSURL fileURLWithPath:midiFilePath];
// Crash is encountered on the following line:
CheckError(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
}
您是否尝试将 NSAppleMusicUsageDescription
添加到您的 Info.plist
?
Starting in iOS 10, your Info.plist file must include a purpose string, for display in the permission alert, for each such item. If your app attempts to access a protected item without you having provided a corresponding purpose string, your app exits.
有关详细信息,请参阅 App Programming Guide for iOS。
我通过 Core Audio Mailing List 收到了 Apple 工程师的一些指导,并在 iOS10 中成功实施了针对此问题建议的解决方法。
通过在调用失败后将 "errno" 值更新为 0,后续对 'MusicSequenceFileLoad' 的调用将生成成功的响应。因此,我修改了我的代码如下:
OSStatus statusOfInitialAttempt = CheckError(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
if (statusOfInitialAttempt == -1) {
errno = 0;
OSStatus statusOfSecondAttempt = CheckErrorAndReturnOnFailure(MusicSequenceFileLoad(self.masterMidiMusicSequence, (__bridge CFURLRef)midiFileURL, 0, 0), "MusicSequenceFileLoad");
if (statusOfSecondAttempt == -1) {
// Handle error case
}
}
... 其中 CheckError() 函数只是根据已知的 OSStatus 代码检查 OSStatus return 值,类似于 this one on GitHub (originally created by Chris Adamson from his blog post / presentation "Core Audio Cranks It Up").
我了解到,根据核心音频邮件列表上发布的内容,此问题有望在未来的 iOS 更新中得到解决。