我正在使用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 {...},但没有任何努力。仍在增加内存使用量......
答案 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
中至少有十几个案例可能有不同的释放要求。