2016年10月9日更新: 2016年9月22日にAppleでレーダー#28425770を次の欠陥のために開いたところ、(レーダー#28327056の)重複としてマークされたため、これは既知のバグのようですiOS10内。
AudioToolbox / MusicPlayer APIメソッド「MusicSequenceFileLoad()」を呼び出してMIDIファイルのコンテンツ(指定されたURLから)をiOS10 iPad Pro(wifiモデル)の音楽シーケンスにロードするときにエラーが発生しました。これをデバッグする際のコミュニティからの支援。
私がこれまでに行うことができた調査/観察:
このコードは、iOS7、8、および9の本番環境で2年以上問題なく動作しており、iOS 10シミュレーターでも問題なく実行されますが、iOS 10.0.1 iPad ProWifiモデルでのみエラーが返されます。
他のデバイスでは再現できず、友達にも試してもらいました。問題なくテストされたデバイス:iPhone 6以降、iPad Mini 4th Gen、iPad ProCellular。
このMIDIファイルを使用するVCが初めて表示されるとき、すべての処理は問題なく実行されます。アプリがクラッシュした場所にVCが読み込まれるのは、2回目(場合によっては3回目)だけです。問題は、100%の確率で一貫して再現できます。
この関数を呼び出してOSStatus結果コードをチェックすると、値-1が返されるだけで、失敗の理由は示されません。
Xcode内でデバッグする場合、クラッシュレポート、例外情報、またはコールスタックは利用できません。
メモリ管理の問題(割り当て、リーク、ゾンビ)のプロファイリングでは、クラッシュに関連する情報は示されていません。ゾンビオブジェクトオプションをオンにしても、ゾンビオブジェクトは表示されませんでした。
アプリケーションを分析しても、メモリが解放されていない領域は見つかりませんでした。
オブジェクトを静的に変更しても影響はなかったため、これはメモリに関連していないようです。
私がこの問題をデバッグできる他の方法について誰かが何か提案があれば、それは大いにありがたいです。当初はメモリ管理に関連しているのではないかと思っていましたが、メモリを適切に処理しており(アプリケーションに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");
}
コアオーディオメーリングリストを介して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コードと照合するだけで、GitHubのこれに似ています(元々はChrisAdamsonがブログ投稿/プレゼンテーション「 CoreAudioCranks ItUp 」から作成したものです)。
この問題は、Core Audioメーリングリストに投稿された内容に従って、将来のiOSアップデートで解決される予定であることを理解しています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加