将NSString拆分为子字符串的大多数内存有效方法

时间:2011-09-12 15:24:37

标签: objective-c ios

我有以下代码:

    int start = [html rangeOfString:@"class=WordSection1>"].location + 24;
    int end = [html rangeOfString:@"<div class=\"endofsections\">"].location;
    self.parts = [[NSMutableArray alloc] init];

    NSString* startHtml = [html substringToIndex:start - 1];
    NSString* mainHtml = [html substringWithRange:NSMakeRange(start - 1, end - start - 1)];
    NSString* endHtml = [html substringFromIndex:end];
    // !! At this point we have the string in memory twice
    [html release];

    [self.parts addObject: startHtml];

    NSArray *splitHtml = [mainHtml componentsSeparatedByString:@"<p class=NumberedParagraph>"];
    //[mainHtml release]; <-- this causes bad access errors. Does the split do a copy or does it just create a new set of pointers but use the same memory?

    for(NSString* part in splitHtml){
        if (first){
            [self.parts addObject: part];
            first = NO;
        } else {
            [self.parts addObject: [NSString stringWithFormat:@"<p class=NumberedParagraph>%@", part]];
        }
     }

    [self.parts addObject:endHtml];

这个问题是html大约是20Mb。我将它拆分为startHtml,mainHtml和endHtml。拆分后我发布html。但是在此版本之前,所有4个NSStrings都在内存中,因此应用程序使用额外的40Mb左右。

然后我拆分mainHtml并将子串分配给名为splitHtml的NSArray,这再次意味着它们存储在内存中两次。我尝试释放mainHtml但这会导致EXC_BAD_ACCESS错误。

在发布问题之前,有没有办法绕过这个对象存储在内存中两次?

我计划用while循环替换for循环,该循环从splitHtml中删除已处理的NSStrings。当splitHtml为空时,将满足循环条件。这是因为部件数组占用更多内存,splitHtml数组占用的内存更少。我是否需要释放每个NSString,或者我可以将其删除并让阵列整体消耗更少的内存?

谢谢,

2 个答案:

答案 0 :(得分:2)

使用rangeOfString:NSScanner或正则表达式解析HTML是徒劳的。它可能适用于您的测试用例,但一旦HTML更改它就会中断。

即。请记住:

<div class=\"endofsections\">

<div    class=\"endofsections\"   id=1 
    title="End Of Sections"  >

class属性两者都相同。

使用正确的HTML解析器。

答案 1 :(得分:1)

嗯..你不能释放mainHtml,因为它是作为自动释放对象创建的,所以在你的函数完成后会释放release,如果那个对象已经被释放它会崩溃。

您可以尝试创建一个额外的函数来拆分字符串并返回数组,也许是在运行函数后释放自己的自动释放池,以确保字符串被释放。