iOS - libical / const char * - 内存使用情况

时间:2012-07-16 13:27:42

标签: iphone objective-c ios icalendar libical

我正在使用libical库来解析iCalendar格式并从中读取我需要的信息。到目前为止它工作得非常好,但有一个奇怪的事情是关于ical。 这是我的代码:

icalcomponent *root = icalparser_parse_string([iCalData cStringUsingEncoding:NSUTF8StringEncoding]);

if (root)
{    
    icalcomponent *currentEvent = icalcomponent_get_first_component(root, ICAL_VEVENT_COMPONENT);

    while (currentEvent)
    {    
        while(currentProperty)
        {    
            icalvalue *value = icalproperty_get_value(currentProperty);
            char *icalString = icalvalue_as_ical_string_r(value); //seems to leak
            NSString *currentValueAsString = [NSString stringWithCString:icalString
                                                                encoding:NSUTF8StringEncoding];
            icalvalue_free(value);
            //...
            //import data
            //...
            icalString = nil;
            currentValueAsString = nil;
            icalproperty_free(currentProperty);
            currentProperty = icalcomponent_get_next_property(currentEvent, ICAL_ANY_PROPERTY);
        } //end while
    } //end while
    icalcomponent_free(currentEvent);
}
icalcomponent_free(root);

// ...

我确实用仪器来检查我的内存使用情况,并且能够发现这条线似乎泄漏了:

char *icalString = icalvalue_as_ical_string_r(value); //seems to leak

如果我复制并粘贴此行5或6次,我的内存使用量将增加约400kb,永远不会再被释放。

icalvalue_as_ical_string_r方法没有免费方法,因为它返回了一个char * ..

有任何建议如何解决这个问题?我将不胜感激任何帮助!

编辑

看一下苹果医生说的如下:

  

要从字符串对象获取C字符串,建议您使用UTF8String。这将使用UTF8字符串编码返回const char *。

const char *cString = [@"Hello, world" UTF8String];
  

您收到的C字符串由临时对象拥有,并且在自动释放时将变为无效。如果要获取永久C字符串,则必须创建缓冲区并复制方法返回的const char *的内容。

但如果使用arc,如何正确释放char *字符串? 我尝试在我的while循环前添加@autorelease {...},但没有任何努力。仍在增加内存使用量......

2 个答案:

答案 0 :(得分:1)

icalvalue_as_ical_string_r返回char *,因为它为结果字符串完成了malloc()。如果你的指针是非NULL,你必须在使用后释放()它。

答案 1 :(得分:1)

小心声明“没有自由方法......因为它正在返回一个字符*”;这绝不是你可以假设的事情。

如果没有文档,您可以查看库的源代码以查看它的作用;例如:

http://libical.sourcearchive.com/documentation/0.44-2/icalvalue_8c-source.html

不幸的是,这个函数可以做很多的不同事情。肯定有一些的情况,在返回的缓冲区上调用free()是正确的,但可能在每种情况下都没有确保。

我认为最好从库的维护者那里请求一个正确的解除分配方法。他们需要清理自己的烂摊子; icalvalue_as_ical_string_r()函数在switch中至少有十几个案例可能有不同的释放要求。