我有以下代码:
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,或者我可以将其删除并让阵列整体消耗更少的内存?
谢谢,
乔
答案 0 :(得分:2)
使用rangeOfString:
,NSScanner
或正则表达式解析HTML是徒劳的。它可能适用于您的测试用例,但一旦HTML更改它就会中断。
即。请记住:
<div class=\"endofsections\">
和
<div class=\"endofsections\" id=1
title="End Of Sections" >
class
属性两者都相同。
使用正确的HTML解析器。
答案 1 :(得分:1)
嗯..你不能释放mainHtml,因为它是作为自动释放对象创建的,所以在你的函数完成后会释放release,如果那个对象已经被释放它会崩溃。
您可以尝试创建一个额外的函数来拆分字符串并返回数组,也许是在运行函数后释放自己的自动释放池,以确保字符串被释放。