1

我使用simpleFTP来请求文档信息。我用仪器检测内存泄漏如下:

在此处输入图像描述

在调用树中,我发现内存泄漏发生在哪里:

在此处输入图像描述

方法“_parseListData”如下:

- (void)_parseListData
{
    NSMutableArray *    newEntries;
    NSUInteger          offset;

    // We accumulate the new entries into an array to avoid a) adding items to the 
    // table one-by-one, and b) repeatedly shuffling the listData buffer around.

    newEntries = [NSMutableArray array];
    assert(newEntries != nil);

    offset = 0;
    do {
        CFIndex         bytesConsumed;
        CFDictionaryRef thisEntry;

        thisEntry = NULL;

        assert(offset <= self.listData.length);
        bytesConsumed = CFFTPCreateParsedResourceListing(NULL, &((const uint8_t *) self.listData.bytes) [offset], self.listData.length - offset, &thisEntry);
        if (bytesConsumed > 0) {
........
}

我不知道如何解决这个问题。

方法“ CFFTPCreateParsedResourceListing”是一个系统方法,它创建__NSDate看第二张图片)。

这就是内存泄漏发生的地方。

4

2 回答 2

0

旧帖子,但有用的解决方案。你可以在这里找到答案BlackRaccoon ftp client。根据创建者的说法,CFFTPCreateParsedResourceListing 方法保留了两倍的 NSDate,要覆盖问题添加下一个代码,请注意此处的注释: FAQ 部分 “实际上,在 WhiteRaccoon 中,如果列出目录,您将泄漏 NSDate。函数 CFFTPCreateParsedResourceListing 在“Apple 的 SDK 存在漏洞。我试图“修补”这个问题,但不能保证它可以正常工作。对于 OS 5.1,它确实可以工作。”

            ........
            if (parsedBytes > 0)
            {
                if (listingEntity != NULL)
                {
                    //----- July 10, 2012: CFFTPCreateParsedResourceListing had a bug that had the date over retained
                    //----- in order to fix this, we release it once. However, just as a precaution, we check to see what
                    //----- the retain count might be (this isn't guaranteed to work).
                    id date = [(__bridge NSDictionary *) listingEntity objectForKey: (id) kCFFTPResourceModDate];
                    if (CFGetRetainCount((__bridge CFTypeRef) date) >= 2)
                        CFRelease((__bridge CFTypeRef) date);

这对我有用

于 2013-06-17T16:59:24.577 回答
0

CFFTPCreateParsedResourceListing函数将 a 返回CFDictionarythisEntry变量中,该变量可能包含NSDate对象。

CFRelease代码完成后应该调用thisEntry

// once we're done with thisEntry
if (thisEntry) {
    CFRelease(thisEntry);
}
于 2012-06-11T08:05:20.290 回答