2015-09-12 35 views
0

我目前正在嘗試使用開源外部庫編寫應用程序。我有可用的源代碼,並且可以隨時根據需要構建新的副本。iOS Core Foundation內存泄漏外部庫

無論如何,在分析我的應用程序時 - 我注意到一些內存泄漏到了庫中。這是小 - 128b一槍 - 但仍然,我寧願而不是有內存泄漏開始。

這是代碼。我編寫的修改後的代碼位於頂部(即泄漏處),原始代碼位於底部(泄漏處)。

CFURLRef getURLFromPath(const char * path) { 
    //modified code to hopefully clean up after myself 
    CFStringRef cfTotalPath = CFStringCreateWithCString (NULL, path, kCFStringEncodingUTF8); 
    CFURLRef cURL = CFURLCreateWithFileSystemPath(NULL, cfTotalPath, kCFURLPOSIXPathStyle, false); 
    CFRelease(cfTotalPath); 

    return cURL; 

    //original code 
    /*CFStringRef cfTotalPath = CFStringCreateWithCString (kCFAllocatorDefault, 
     path, kCFStringEncodingUTF8); 

    return CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfTotalPath, 
     kCFURLPOSIXPathStyle, false);*/ 

} 

我是比較新的iOS編程;我正在調試一個實際的設備,並且我知道有時候儀器會在泄漏時給出誤報。

這真令人氣憤,因爲這一塊代碼是我的泄漏堆棧跟蹤中的最後一步...我真的不知道如何解決它。

編輯:從我讀過的,蘋果不介意在這裏和那裏偶爾的內存泄漏;我將繼續編程,因爲此過程僅在我的應用程序中每個音樂文件發生一次 - 分析BPM的軌道(分析後會保存)。

編輯2:這裏的指的是的代碼。我已經添加了所有CFRelease(fileURL),但它繼續泄漏:

uint_t aubio_sink_apple_audio_open(aubio_sink_apple_audio_t *s) { 

    if (s->samplerate == 0 || s->channels == 0) return AUBIO_FAIL; 

    AudioStreamBasicDescription clientFormat; 
    memset(&clientFormat, 0, sizeof(AudioStreamBasicDescription)); 
    clientFormat.mFormatID   = kAudioFormatLinearPCM; 
    clientFormat.mSampleRate  = (Float64)(s->samplerate); 
    clientFormat.mFormatFlags  = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
    clientFormat.mChannelsPerFrame = s->channels; 
    clientFormat.mBitsPerChannel = sizeof(short) * 8; 
    clientFormat.mFramesPerPacket = 1; 
    clientFormat.mBytesPerFrame = clientFormat.mBitsPerChannel * clientFormat.mChannelsPerFrame/8; 
    clientFormat.mBytesPerPacket = clientFormat.mFramesPerPacket * clientFormat.mBytesPerFrame; 
    clientFormat.mReserved   = 0; 

    AudioFileTypeID fileType = kAudioFileWAVEType; 
    CFURLRef fileURL = getURLFromPath(s->path); 
    bool overwrite = true; 
    OSStatus err = noErr; 
    err = ExtAudioFileCreateWithURL(fileURL, fileType, &clientFormat, NULL, 
    overwrite ? kAudioFileFlags_EraseFile : 0, &s->audioFile); 
    if (err) { 
    char_t errorstr[20]; 
    AUBIO_ERR("sink_apple_audio: error when trying to create %s with " 
     "ExtAudioFileCreateWithURL (%s)\n", s->path, 
     getPrintableOSStatusError(errorstr, err)); 
    goto beach; 
    } 
    if (createAubioBufferList(&s->bufferList, s->channels, s->max_frames * s->channels)) { 
    AUBIO_ERR("sink_apple_audio: error when creating buffer list for %s, " 
     "out of memory? \n", s->path); 
    goto beach; 
    } 

    //added release code 
    CFRelease(fileURL); 
    return AUBIO_OK; 

beach: 
    //added release code 
    CFRelease(fileURL); 
    return AUBIO_FAIL; 
} 

EDIT3:下面是截圖 Instrument panel

EDIT4:原來解決實際工作時,Xcode拒絕加載新版本我的框架儘管我一直在重新編譯它。所以,我必須清除框架的所有引用 - 包括清理構建信息頁 - 並重新添加「固定」版本。

+0

在你的代碼上運行分析器。它是否報告了您的代碼的任何問題?如果是這樣,解決問題,然後看看你是否仍然有泄漏。 – rmaddy

+0

嗨rmaddy,我剛剛對我的項目進行了分析。唯一出現的錯誤是圍繞單元格原型ID和啓動畫面(由於我的故事板不完整)。我的項目仍然非常不完整和小,我想我應該在繼續下一個大塊之前執行「代碼清理」並檢查。這就是我發現這個非常小的內存泄漏的原因 –

+0

您是在模擬器還是真實設備上測試?只能在真實設備上進行泄漏測試。 – rmaddy

回答

1

您在使用CFURLCreateWithFileSystemPath創建的退回CFURLRef泄漏。

您應該將函數從getURLFromPath重命名爲createURLFromPath,以指示將返回的CFURLRef的所有權傳遞給調用方。然後任何調用該方法的代碼負責在完成時發佈CFURLRef

+0

謝謝你的幫助;我在調用它的代碼中添加了CFRelease(fileURL),但仍然遇到鏈接。我已將調用代碼添加到我的原始問題中。 –

+0

嘿rmaddy!你的解決方案確實結束了工作;儘管我的構建和清理,XCode不斷緩存舊版本的框架。我最終不得不刪除對庫的所有引用(包括從框架搜索路徑中刪除文件夾引用),並讀取新的引用。 然而,這個框架還是從0.41升級到了.42,所以我也得到了一個免費的bug修復升級! –