2012-05-02 3 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. 그리고 또 다른 질문입니다. NSRange를 공개해야합니까?

+0

내 조언 -> 좀 봐 : https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html 이것은 장기적으로 당신을 도울 것입니다 .. –

+0

당신은 근본적인 문제가 있으며 그것이 무엇인지를 다른 사람들이 이해할 수 있도록 설명하는 것이 좋습니다. 이것은 단순히 "내 codz 수정"문제가 아닙니다. 투표가 내려져야한다고 생각하지 않아 워렌 버튼이 당신을 위해 그것을 확인한 것 같습니다. – Jim

+0

반환 된 객체가 autorelease라는 사실을 알지 못했습니다. 내가 자바와 함께 몇 가지 경험을 가지고 있지만 유지 및 릴리스 메모리 관리를하지 ... – Charles

답변

1

바로 여기

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

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

당신은 당신의 원본 객체를 삭제하고 그것을 다시 끼 오토 릴리즈이

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

[wantedCharacters release]; 

호출 할 때 충돌합니다

하나

마지막

[wantedCharacters release]; 
+0

감사합니다. 나는 여전히 객관적인 C의 메모리 관리에 익숙하지 않기 때문에 return 문이 autorelease라는 것을 알지 못했다. – Charles

+0

위의 마지막 코멘트를 참조하십시오. – Jim

0

이 당신이 할당 된 객체에 대한 참조를 잃게됩니다 코드에서 몇 가지 실수가 있고, 예를 따를 것이다, 그러나 몇 가지 :

  1. 그들 모두를위한 가장 쉬운 해결책은있다 당신이 alloc 전화 (그 개체에 대한 release 제거) 곳, 예를 들어, autorelease를 사용하는 : 당신이 변수를 만들 때

    NSString* cleanStringOutput=[[[NSString alloc] initWithString:@""] autorelease]; 
    
  2. 은 나중에에 할당, 필요의 t가 없습니다 오, 예를 들어, 할당 : 일반적으로

    NSCharacterSet* wantedCharacters; // no need for alloc here 
    wantedCharacters=[ NSCharacterSet characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnm"]; 
    
  3. 를 - 개체를 할당하지 않은 경우, 당신이 그것을 공개하지 않습니다. 위의 그것을 초기화/ALLOC 필요가 없습니다 -

+1

autorelease를 적용하고 메모리 관리를 제대로 배우지 못하는 것이 IMO의 장기적인 해결 방법이 아닙니다. –

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

는 오토 릴리즈 캐릭터 라인을 돌려줍니다.

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

그래서 아마 문제를 일으킬 수
[currentLetter release]; 

를 호출.

0

당신의 ALLOC를 잊지는/다음 편의 기능을 사용하여 재 할당하는 wantedCharacters 객체를 초기화하기. 재 할당은 첫 번째 객체로 좀비를 만듭니다.

편의 함수는 새 객체 인스턴스를 자동 해제 풀에 넣습니다.

그런 다음 릴리스를 호출합니다. 한 번만 유지되었으므로 할당이 해제됩니다.

나중에 autorelease 풀에서 release를 호출하지만 이미 할당이 해제되었습니다. 이로 인해 충돌이 발생합니다.

관련 문제