2012-05-02 105 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池調用它的釋放,但它已經被釋放。這會導致崩潰。

相關問題