2012-05-02 108 views
1

这是我写的一段代码,用于清理一串不需要的字符和双倍间距。 但是,我似乎误解了某处的内存管理,并一直导致EXC_BAD_ACCESS错误。代码在发布语句被删除但是会导致内存泄漏时在功能上工作良好。为什么此代码会导致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; 
} 

请原谅我,如果我只是问了一些痛苦明显的东西。

P.S.还有一个问题。是否有必要释放NSRange?

+0

我的建议 - >看看https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html这将帮助你从长远来看.. –

+0

你有一个基本问题,它可以说明其他人理解它是什么。这不仅仅是一个“解决我的问题”的问题。我认为它不应该被投票。它看起来像沃伦伯顿为你确定。 – Jim

+0

我只是没有意识到返回的对象是autorelease。我有一些与Java的经验,但没有保留和释放内存管理... – Charles

回答

1

就在这里

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

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

你放弃你原来的对象,取而代之的是一个自动释放一个

这将崩溃,当你调用

[wantedCharacters release]; 

做这个

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

并忘记最后一个

[wantedCharacters release]; 
+0

谢谢!我仍然不熟悉Objective C的内存管理,所以我没有意识到return语句是autorelease。 – Charles

+0

查看我上面的最后一条评论。 – Jim

0

有你的代码,使你失去了参考分配的对象几次失误,以及一个例子可循,但几件事情:

  1. 为所有这些最简单的解决方案,是使用autorelease无论你叫alloc(并删除release这些对象),例如:

    NSString* cleanStringOutput=[[[NSString alloc] initWithString:@""] autorelease]; 
    
  2. 当你创建了一个变量,后来才分配给它,也没有必要ŧ Ø分配,例如:

    NSCharacterSet* wantedCharacters; // no need for alloc here 
    wantedCharacters=[ NSCharacterSet characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"]; 
    
  3. 一般 - 如果你没有分配对象,你不松开。

+1

应用自动释放和不正确学习内存管理不是一个很好的长期解决IMO。 –

0
currentLetter=[NSString stringWithFormat:@"%c",[input characterAtIndex:i]]; 

返回一个字符串自动释放 - 无需分配/初始化上面它。

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

所以调用

[currentLetter release]; 

可能会引起问题。

0

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

便利函数将新对象实例放入autorelease池中。

然后你呼叫发布。由于它只保留一次,它会被释放。

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

相关问题