我在ARC中使用iOS5中的塊來使用AVAudioPlayer播放永不結束的音頻錄製循環。我在收到AVAudioPlayerDidFinishRecording消息後分配一個新的AVAudioPlayer,該消息啓動一個遞歸循環。在播放120個左右音頻剪輯後,我的應用程序一直崩潰。我可以看到它在每個音頻文件加載時佔用越來越多的內存,但從不釋放內存。遞歸塊==內存不足沉默崩潰
我使用的是單個AVAudioPlayer屬性,所以我期待ARC每次分配新玩家時清理舊實例。
能塊以某種方式導致老AVAudioPlayers留下來?
使用Observer監視玩家並啓動/分配新玩家會更好嗎?
非常感謝您的幫助!
-(void)playNextAudioItem{
//get ready to load audio doc from iCloud
NSURL *ubiquitousContainer = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if(ubiquitousContainer){
//query iCloud
query = [[NSMetadataQuery alloc]init];
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"(%K == %@)", NSMetadataItemFSNameKey, [NSString stringWithFormat:@"%@.caf", audioItemGUID]];
[query setPredicate:pred];
[[NSNotificationCenter defaultCenter] addObserverForName:NSMetadataQueryDidFinishGatheringNotification object:query queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif){
//iCloud query finished gathering data
[query disableUpdates];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
NSMetadataItem *item1 = [query resultAtIndex:0];
audioCurrentVerse = [[audioDoc alloc] initWithFileURL:[item1 valueForAttribute:NSMetadataItemURLKey]];
//open the audio file
[audioCurrentVerse openWithCompletionHandler:^(BOOL success) {
if(success){
//configure the session and play the audio file
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:YES error:nil];
NSError *error = nil;
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
audioPlayer = [[AVAudioPlayer alloc] initWithData:audioCurrentVerse.data error:&error];
audioPlayer.numberOfLoops = 0;
audioPlayer.delegate = self;
if([audioPlayer prepareToPlay]){
[audioPlayer play];
}
}
}];
[query stopQuery];
query = nil;
}];
[query startQuery];
}
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
//get an identifier for the next audio item
audioItemIndex++;
if(audioItemIndex >= rsAudioItems.recordCount){
verseIndex = 0;
}
audioItemGUID = [rsAudioItems getRow:audioItemIndex andColumnNamed:@"audioItemGUID"];
//recursive call to play the next audio item
NSLog([NSString stringWithFormat:@"%d", playCount++]);
[self playNextAudioItem];
}
如果您包含一些相關的代碼,它會更容易有幫助。 –
關於使用嵌套塊的一般規則:不要。內存管理本身就很糟糕。改用while循環。 –
您可能需要花時間創建[SSCCE](http://sscce.org);你可以自己解決這個問題。它肯定會讓別人更容易幫助你。 –