外部库中的iOS Core Foundation内存泄漏

时间:2015-09-12 19:22:20

标签: ios objective-c memory-leaks 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编程比较陌生;我正在调试一个实际的设备,我知道有时仪器会在泄漏时给出误报。

这令人气愤,因为这一段代码是我泄漏的堆栈跟踪的最后一步......我真的不知道如何修复它。

编辑:据我所知,Apple并不介意偶尔会出现内存泄漏;我将继续编程,因为此过程仅在我的应用程序中为每个音乐文件发生一次 - 分析BPM的轨道(一旦分析就会保存)。

Edit2:这是引用代码。我添加了所有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拒绝加载我的框架的新版本,即使我不断重新编译它。所以,我不得不清除框架的所有引用 - 包括清理构建信息页面 - 并重新添加“修复”版本。

1 个答案:

答案 0 :(得分:1)

您正在泄露使用CFURLRef创建的已返回CFURLCreateWithFileSystemPath

您应该将该函数从getURLFromPath重命名为createURLFromPath,以表明返回的CFURLRef的所有权正在传递给调用者。然后,调用该方法的任何代码都负责在完成时释放CFURLRef