1

这是我为清理一串不需要的字符和双倍间距而编写的一段代码。但是,我似乎在某处误解了内存管理,它不断导致 EXC_BAD_ACCESS 错误。当释放语句被删除时,代码在功能上工作正常,但这会导致内存泄漏。

-(NSString*) cleaningString:(NSString*) input  {
NSCharacterSet* wantedCharacters=[[NSCharacterSet alloc] init];

   wantedCharacters=[ NSCharacterSet    
 characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];


NSString* cleanStringOutput=[[NSString alloc] initWithString:@""];
NSString* currentLetter =[[NSString alloc] initWithString:@" "];
NSRange unwantedCharacters=[currentLetter rangeOfCharacterFromSet:wantedCharacters];

for (int i=0; i<input.length; i++) {
    currentLetter=[NSString stringWithFormat:@"%c",[input characterAtIndex:i]];
    unwantedCharacters=[currentLetter rangeOfCharacterFromSet:wantedCharacters];
    doubleSpace=YES;
    if (i<input.length-1) {
        if (([currentLetter isEqualToString:@" "])&&([[NSString stringWithFormat:@"%c",[input characterAtIndex:i+1]] isEqualToString:@" "])) {
            doubleSpace=NO;}
    }
    else {
        if ([currentLetter isEqualToString:@" "]) {
            doubleSpace=NO;
        }
    }
    if ((unwantedCharacters.location!=NSNotFound)&&(doubleSpace))
    {
        cleanStringOutput=[NSString stringWithFormat:@"%@%@", cleanStringOutput, currentLetter];
    }
}
if (cleanStringOutput.length>0){
    if ([[NSString stringWithFormat:@"%c",[cleanStringOutput characterAtIndex:0]] isEqualToString:@" "]){
        cleanStringOutput=[cleanStringOutput substringFromIndex:1];
    }
}

[currentLetter release];
[wantedCharacters release];
[cleanStringOutput autorelease];
return cleanStringOutput;
}

如果我只是问了一些非常明显的问题,请原谅我。

PS 还有一个问题。是否有必要释放 NSRange?

4

4 回答 4

1

就在这儿

NSCharacterSet* wantedCharacters=[[NSCharacterSet alloc] init];

   wantedCharacters=[ NSCharacterSet    
 characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];

您丢弃原始对象并用自动释放的对象替换它

当你打电话时哪个会崩溃

[wantedCharacters release];

做这个

NSCharacterSet* wantedCharacters=[ NSCharacterSet    
 characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];

忘记最后一个

[wantedCharacters release];
于 2012-05-02T21:04:46.073 回答
0
currentLetter=[NSString stringWithFormat:@"%c",[input characterAtIndex:i]];

返回一个自动释放的字符串——不需要在上面分配/初始化它。

NSString* currentLetter =[[NSString alloc] initWithString:@" "];

所以打电话

[currentLetter release];

很可能会引起问题。

于 2012-05-02T21:02:16.710 回答
0

您分配/初始化一个wantedCharacters对象,然后使用便利功能重新分配它。重新分配使用第一个对象创建一个僵尸。

便利函数将新对象实例放入自动释放池中。

然后你调用释放。由于它只保留一次,它被释放。

后来,自动释放池调用释放它,但它已经被释放。这会导致崩溃。

于 2012-05-02T21:18:32.303 回答
0

您的代码中有几个错误会导致您丢失对已分配对象的引用,下面将举一个示例,但有几点:

  1. 所有这些最简单的解决方案是autorelease在您调用的任何地方使用alloc(并删除release这些对象),例如:

    NSString* cleanStringOutput=[[[NSString alloc] initWithString:@""] autorelease];
    
  2. 当您创建一个变量只是为了稍后分配给它时,不需要分配,例如:

    NSCharacterSet* wantedCharacters; // no need for alloc here
    wantedCharacters=[ NSCharacterSet characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"];
    
  3. 一般来说——如果你没有分配对象,你就不会释放它。

于 2012-05-02T21:02:12.723 回答