Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 试图分割一个非常大的字符串_Objective C_Ios_Nsstring - Fatal编程技术网

Objective c 试图分割一个非常大的字符串

Objective c 试图分割一个非常大的字符串,objective-c,ios,nsstring,Objective C,Ios,Nsstring,可能重复: 我正在尝试拆分一个20Mb的字符串。我尝试过使用字符串分离的组件,但它消耗了太多的内存。我认为这是因为它分割了字符串,但也保留了原始字符串的完整性。这意味着字符串将有效地存储在内存中两次(即使我在拆分后立即释放原始字符串,这仍然是一个问题) 我对Objective C非常陌生。我试图编写一些代码,在将子字符串添加到找到的字符串数组中时,将其从原始字符串中删除。其思想是,当找到的字符串的可变数组变大时,原始字符串变小。唯一的问题是它会泄漏内存并崩溃。如果有人能告诉我我做错了什么,那你

可能重复:

我正在尝试拆分一个20Mb的字符串。我尝试过使用字符串分离的组件,但它消耗了太多的内存。我认为这是因为它分割了字符串,但也保留了原始字符串的完整性。这意味着字符串将有效地存储在内存中两次(即使我在拆分后立即释放原始字符串,这仍然是一个问题)

我对Objective C非常陌生。我试图编写一些代码,在将子字符串添加到找到的字符串数组中时,将其从原始字符串中删除。其思想是,当找到的字符串的可变数组变大时,原始字符串变小。唯一的问题是它会泄漏内存并崩溃。如果有人能告诉我我做错了什么,那你就太棒了

    NSRange range = [mainHtml rangeOfString:@"<p class=NumberedParagraph>"];
    int counter = 1;

    // locations will == int max if it can't find any more occurances
    while (range.location < [mainHtml length]) {
        NSString *curStr;
        NSRange curStrRange;

        NSRange rangeToSearchIn = NSMakeRange(range.location+1, [mainHtml length] - range.location - 1);
        NSRange nextRange = [mainHtml rangeOfString:@"<p class=NumberedParagraph>" options:NSCaseInsensitiveSearch range:rangeToSearchIn];

        if (nextRange.location > [mainHtml length])
        {
            // This is the last string - get everything up to the end of the file
            curStrRange = NSMakeRange(0, [mainHtml length]);
            curStr = [mainHtml substringFromIndex:range.location];
        } else {
            curStrRange = NSMakeRange(range.location, nextRange.location - range.location);
            curStr = [mainHtml substringWithRange:curStrRange];
        }

        // Remove the substring just processed from the orignal string
        // * it crashes here, normally on the 3rd itteration
        mainHtml = [mainHtml substringFromIndex:curStrRange.location + curStrRange.length];
        range = [mainHtml rangeOfString:@"<p class=NumberedParagraph>"];

        [self.parts addObject:curStr];
    }
NSRange range=[mainHtml rangeOfString:@“

”; int计数器=1; //如果找不到任何其他事件,位置将==int max 而(range.location<[mainHtml长度]){ NSString*curStr; NSRange curStrRange; NSRange rangeToSearchIn=NSMakeRange(range.location+1,[mainHtml长度]-range.location-1); NSRange nextRange=[mainHtml rangeOfString:@“

”选项:nscaseinsensitive搜索范围:rangeToSearchIn]; 如果(nextRange.location>[mainHtml长度]) { //这是最后一个字符串-获取文件末尾的所有内容 curStrRange=NSMakeRange(0,[mainHtml长度]); curStr=[mainHtml substringFromIndex:range.location]; }否则{ curStrRange=NSMakeRange(range.location,nextRange.location-range.location); curStr=[mainHtml substringWithRange:curStrRange]; } //从原始字符串中删除刚刚处理的子字符串 //*它在这里崩溃,通常在第三天 mainHtml=[mainHtml substringFromIndex:curStrRange.location+curStrRange.length]; range=[mainHtml rangeOfString:@“

”; [self.parts addObject:curStr]; }


我相信你没有任何漏洞
substringFromIndex:
返回一个自动删除的字符串,因此它可能会在内存中保存一次以上的迭代。您可以创建自己的
substringfromfromindex:
方法(例如:
createsubstringfromfromindex
),该方法将返回一个字符串保留字符串,您可以手动释放该字符串

+(NSString *)createSubstringFromIndex:(NSUInteger)index string:(NSString *)string{
    int newLen = [string length] - index;
    if(newLen<=0)
        return @"";   // or nil
    char *cStr = malloc(newLen+1);
    for(int i=index; i<[string length]; i++){
        cStr[i-index]=[string characterAtIndex:i];
    }
    cStr[newLen]='\0';
    NSString *retStr = [[NSString alloc] initWithCString:cStr encoding:NSASCIIStringEncoding];
    free(cStr);
    return retStr;
}
为此:

NSString *newHtmlString = [[self class] createSubstringFromIndex:curStrRange.location + curStrRange.length string:mainHtml];
[mainHtml release];                ///mainHtml should be retained before the while loop starts
mainHtml = newHtmlString;

我认为@babbidi的想法是正确的。mainHtml很大,您有许多自动删除的副本(每个迭代一个副本)没有发布。尝试在代码中添加以下@autorelease,以释放每个循环末尾的所有自动释放对象。如果您没有使用MacOSX10.7,那么您只需要在主循环之外手动创建自动释放池,并在每次迭代中将其耗尽一次

NSRange range = [mainHtml rangeOfString:@"<p class=NumberedParagraph>"];
int counter = 1;

// locations will == int max if it can't find any more occurances
while (range.location < [mainHtml length]) {
    @autorelease {
        NSString *curStr;
        NSRange curStrRange;

        NSRange rangeToSearchIn = NSMakeRange(range.location+1, [mainHtml length] - range.location - 1);
        NSRange nextRange = [mainHtml rangeOfString:@"<p class=NumberedParagraph>" options:NSCaseInsensitiveSearch range:rangeToSearchIn];

        if (nextRange.location > [mainHtml length])
        {
            // This is the last string - get everything up to the end of the file
            curStrRange = NSMakeRange(0, [mainHtml length]);
            curStr = [mainHtml substringFromIndex:range.location];
        } else {
            curStrRange = NSMakeRange(range.location, nextRange.location - range.location);
            curStr = [mainHtml substringWithRange:curStrRange];
        }

        // Remove the substring just processed from the orignal string
        // * it crashes here, normally on the 3rd itteration
        mainHtml = [mainHtml substringFromIndex:curStrRange.location + curStrRange.length];
        range = [mainHtml rangeOfString:@"<p class=NumberedParagraph>"];

        [self.parts addObject:curStr];
    }
}
NSRange range=[mainHtml rangeOfString:@“

”; int计数器=1; //如果找不到任何其他事件,位置将==int max 而(range.location<[mainHtml长度]){ @自动释放{ NSString*curStr; NSRange curStrRange; NSRange rangeToSearchIn=NSMakeRange(range.location+1,[mainHtml长度]-range.location-1); NSRange nextRange=[mainHtml rangeOfString:@“

”选项:nscaseinsensitive搜索范围:rangeToSearchIn]; 如果(nextRange.location>[mainHtml长度]) { //这是最后一个字符串-获取文件末尾的所有内容 curStrRange=NSMakeRange(0,[mainHtml长度]); curStr=[mainHtml substringFromIndex:range.location]; }否则{ curStrRange=NSMakeRange(range.location,nextRange.location-range.location); curStr=[mainHtml substringWithRange:curStrRange]; } //从原始字符串中删除刚刚处理的子字符串 //*它在这里崩溃,通常在第三天 mainHtml=[mainHtml substringFromIndex:curStrRange.location+curStrRange.length]; range=[mainHtml rangeOfString:@“

”; [self.parts addObject:curStr]; } }


如果(nextRange.location>[mainHtml length])
我不认为这是对的,是不是应该是
=
?我不确定目标C,但我知道在其他语言中(C#)索引是基于0的,而长度不是,所以最后一个字符的长度应该是-1。不过我会查出来的。谢谢。你是第一个真正为我提供代码来解决问题的人,而不是一些抽象的“你可以做一些类似的事情…”的想法,然后我不得不尝试为这些想法编写代码。啊,但它不起作用。它使用越来越多的RAM,然后在此行崩溃:NSString*retStr=[[NSString alloc]initWithCString:cStr encoding:NSASCIIStringEncoding];您是否正在循环中释放
mainHtml
?是的。我不明白为什么它不起作用。你能提供一个大样本的
mainHtml
?+1如果创建了很多小的自动释放对象,请使用自动释放池!自动释放池修复了它!一个问题是它现在真的很慢。在对babbidi回答的评论中,我链接到一些C代码,这些代码也没有泄漏,但速度非常慢。这仅仅是因为我在分配新的htmlString并将其分配给现在发布的htmlString时移动了20mb的数据吗?我能做些什么吗?谢谢,Joe。@user940516您可以做一些不需要自动释放池的事情,这样可以大大提高性能。不要复制主HTML。相反,使用NSValue构建一个范围数组,如果只在末尾需要子字符串,则应使用范围数组构建此数组。这最多需要约40 MB的内存(给或取一点开销)。
NSRange range = [mainHtml rangeOfString:@"<p class=NumberedParagraph>"];
int counter = 1;

// locations will == int max if it can't find any more occurances
while (range.location < [mainHtml length]) {
    @autorelease {
        NSString *curStr;
        NSRange curStrRange;

        NSRange rangeToSearchIn = NSMakeRange(range.location+1, [mainHtml length] - range.location - 1);
        NSRange nextRange = [mainHtml rangeOfString:@"<p class=NumberedParagraph>" options:NSCaseInsensitiveSearch range:rangeToSearchIn];

        if (nextRange.location > [mainHtml length])
        {
            // This is the last string - get everything up to the end of the file
            curStrRange = NSMakeRange(0, [mainHtml length]);
            curStr = [mainHtml substringFromIndex:range.location];
        } else {
            curStrRange = NSMakeRange(range.location, nextRange.location - range.location);
            curStr = [mainHtml substringWithRange:curStrRange];
        }

        // Remove the substring just processed from the orignal string
        // * it crashes here, normally on the 3rd itteration
        mainHtml = [mainHtml substringFromIndex:curStrRange.location + curStrRange.length];
        range = [mainHtml rangeOfString:@"<p class=NumberedParagraph>"];

        [self.parts addObject:curStr];
    }
}