2012-01-04 64 views
1

我正在編寫一個iPhone應用程序,並且有一些內存問題。這是下面的代碼:程序崩潰在Xcode中沒有顯示錯誤

NSURL *url = [curItem valueForProperty: MPMediaItemPropertyAssetURL]; 

AVURLAsset *asset = [AVURLAsset URLAssetWithURL: url options:nil]; 

NSError *error = nil; 

AVAssetReader* reader = [[AVAssetReader alloc] initWithAsset:asset error:&error]; 

AVAssetTrack* track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 

NSMutableDictionary* audioReadSettings = [NSMutableDictionary dictionary]; 
[audioReadSettings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] 
        forKey:AVFormatIDKey]; 

AVAssetReaderTrackOutput* readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:audioReadSettings]; 

[reader addOutput:readerOutput]; 

[reader startReading]; 

CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer]; 

while(sample != NULL) 
{ 
    sample = [readerOutput copyNextSampleBuffer]; 

} 
CFRelease(sample); 

我讀從用戶的iTunes資料庫中的歌曲(curItem是當前歌曲),如果我離開的最後一行:CFRelease(sample)代碼,該程序將停止 - 沒有錯誤顯示 - 它只是崩潰。如果我註釋掉了這一行,我當然會遇到內存問題,並且在得到「收到內存警告」後,代碼會在第四首歌曲中崩潰。

我在做什麼錯?

回答

1

命名約定copyNextSampleBuffer意味着您擁有返回的對象,因此您可以正確釋放它,但是您在循環中多次調用copyNextSampleBuffer方法,並覆蓋前一個副本而不釋放它。

當你最終調用CFRelease時,你將它調用一個你剛剛檢查過的變量爲NULL。據this StackOverflow answer,呼籲CFRelease對NULL是不是安全的,所以這就是爲什麼你崩潰:

你需要做的,而不是你是什麼while循環中的呼叫釋放您覆蓋之前的變量,像這樣:

CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer]; 

while(sample != NULL) 
{ 
    CFRelease(sample); 
    sample = [readerOutput copyNextSampleBuffer]; 
} 

如果這樣不能解決您的崩潰問題(即使它確實如此),請嘗試在您的代碼上運行靜態分析器(選擇Xcode中的產品菜單中的分析)並查看是否報告了任何潛在的泄漏或過度版本。請記住,你得到的每一個黃色和藍色的警告是一個潛在的崩潰,所以試圖解決所有問題。

編輯:它只是發生在我身上,你的循環沒有多大意義 - 爲什麼你一遍又一遍地讀取樣本,然後把它們扔掉?你是否可能在你的while循環中得到NULL檢查錯誤,你實際上是想寫這個呢?

CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer]; 

while(sample == NULL) 
{ 
    sample = [readerOutput copyNextSampleBuffer]; 
} 

CFRelease(sample); 

這也應該沒問題,因爲在這種情況下,您明確檢查該示例在釋放之前不是NULL。儘管在做任何事情之前你仍然扔掉樣本,並且如果readerOutput不包含樣本,也會冒無限循環的風險。

0

使用autorelease或ARC來擺脫「太早發佈syndrom」。在這兩種情況下,發佈任務都由其他人管理。對於一個新項目,我建議ARC。

相關問題