2011-03-12 2 views
1

내가 같은 인터페이스가 있다고 가정 누출 : 나는 다른 파일에서이 클래스를 사용하는 경우간단한 문제는

@interface it:NSObject 
{ 
    NSString* string; 
} 
@end 

@implement it 
-(id)init 
{ 
    if(self = [super init]){ 
    self.string = [[NSString alloc]init]; 
    } 
} 

-(void)dealloc 
{ 
    [self.string release]; 
    [super release]; 
} 
@end 

을하고 나는이 전화 :

it ait = [[it allow] init]; 
NSString* anotherString = [[NSString alloc] init]; 
ait.string = anotherString; 
[anotherString release]; 

윌이 원인 문자열은 메모리 누수의 init 메서드에 할당 된? 문자열이 참조되지 않고 자동 출시되지 않기 때문에. init 메소드에 문자열을 할당하지 않으면 다른 문자열을 할당하기 전에 ait.string을 호출 할 때 어떤 일이 발생합니까?

답변

1

나는 당신이 일을 self.string에 대한 구현에

@synthesize string; 

@property (nonatomic, retain) NSString *string; 
사용자 인터페이스

을 필요가 있다고 생각합니다.

그런 다음, 당신이 당신의 init 메소드에

self.string = [[NSString alloc] init]; 

을 수행 할 때 문자열은 실제로 1의 유지 카운트 문자열을 반환합니다 2 [[NSString alloc] init] 때문에의 유지 수를 가질 것이며, self.string =를 사용하여 객체를 유지합니다 속성이 '보유'로 선언 되었기 때문에 다시 나타납니다. 이로 인해 메모리 누수가 발생하지만 다음을 수행하여 문제를 해결할 수 있습니다.

-(id)init 
{ 
    if(self = [super init]){ 
    self.string = @"initString"; 
    } 
} 

또는 그와 비슷한 내용으로 해결할 수 있습니다.

그런 다음 실제 질문에 위와 같이 수행하면 self.string =으로 재 할당 할 때 'retain'로 표시된 속성이 새 객체를 유지하기 전에 현재 객체를 해제하기 때문에 초기화 할 때 할당 된 문자열이 누출되지 않습니다.

초기화 메서드에서 self.string에 문자열을 할당하지 않으면 self.string이 단지 nil을 반환하기 때문에 문제가되지 않습니다. 그러면 해당 값을 프로그램에서 처리 할 수 ​​있습니다.

+0

또한, dealloc에서 문자열 (또는'[string release];하지만'* [self.string release];가 아닌)을 해제하려면'self.string = nil;'이어야합니다. – DarkDust

+1

대부분의 경우 문자열에 대한 복사 속성을 유지하고 유지하지 않아야합니다. – Eiko

0
@interface it:NSObject 
{ 
    NSString* string; 
} 

//you should declare a property in order to call it with 'self' prefix 
@property (nonatomic, retain) NSString* string; 

@end 


@implementation it 

//you should synthesize your property 
@synthesize string; 

-(id)init 
{ 
    if(self = [super init]){ 
    //you don't to initialize NSString right here (memory leak will have place) 
    //self.string = [[NSString alloc]init]; 

    //you can store a default value like this (can be omitted): 
    self.string = @"Default value"; 
    } 
    return self; 
} 

-(void)dealloc 
{ 
    [self.string release]; 
    [super release]; 
} 
@end 

그리고이 클래스의 메모리 관리에 관한 모든 것이 잘 될 것입니다.

+0

...'return self; ' –

+0

감사합니다. 편집 된 – knuku

0

이로 인해 에 할당 된 문자열이 메모리 누수가됩니까? 부터 문자열이 참조되지 않고 이 자동으로 재생되지 않습니다.

예. 당신은 그것을 가지고있는 것 같습니다. 내가 초기화 방법에 문자열을 ALLOC하지 않으면 내가 그것을 anotherString를 할당 직전 ait.string 를 호출 할 때

, 어떤 일이 일어날 것인가?

당신은 당신이 unknownObject이 참조 될지 모르는 다음과 같은 경우에 의미합니까 -?

It *ait = [[It allow] init]; 
NSString *unknownObject = ait.string; 

이것은 넌센스이다.접근 자 메서드를 추가하는 것을 잊었습니까?

Objective-c는 Java와 같은 인스턴스 변수에 '도트 구문'을 사용하지 않습니다. 'it'클래스의 인스턴스가있는 경우 접근 자 'getter'메서드를 호출하여 해당 인스턴스 외부에서 변수 ''에만 액세스 할 수 있습니다. 이것은 선택 사항이 아닙니다. self.string은 메소드 호출 [self string]에 대한 바로 가기이며 사용자가 보여준 코드에는이 메소드가 없습니다. 접근 방법을 가정

다른 곳에서 정의 된 인스턴스 변수는이이 전무 같다 (이 세계 최악의 변수 이름) 문자열을했다. Objective-c에서는 다른 언어가 유사한 언어를 처리하는 것과는 다른 동작을하기 때문에 매우 조심스럽게 객체를 처리해야합니다. null. 이 목표 - C에서

괜찮 :

NSString *nilString = nil; 
[nilString writeToFile:@"/this_file_cannot_exist.data"]; 

많은 다른 언어 여기에 충돌하거나 예외를 던질 것입니다; 작업이 실패하지만 앱이 계속 실행될 수 있으므로 위험 할 수 있습니다. 다른 언어로이 많이 볼 수 있기 때문에 그것은 또한, 큰 상점 수 있습니다 .. 목표 - C '경우 (..)'라인 전혀 필요하지 않습니다에

someObject = controller.currentValue() 
if(someObject!=null) 
    someObject.writeToFile("myFile.data") 

.

init 메소드와 dealloc 메소드에서 접근 자 메소드를 호출하지 않도록주의해야합니다. 그러면 하위 클래스가 손상 될 수 있습니다. 대신

- (void)dealloc { 
    [self.string release]; // This is [[self string] release] 
    ... 

당신은 [자기 문자열]에 대한 호출이 불필요 위험한 것으로뿐만 아니라

- (void)dealloc { 
    [string release]; 
    ... 

를 사용해야합니다. 동일은

if(self=[super init]){ 
    self.string = [[NSString alloc]init]; // shortcut for [self setString:[[NSString alloc] init]] 
    ... 

그냥 self.string를 사용하기 위해 당신은 @property를 놓치고

if(self=[super init]){ 
    string = [[NSString alloc] init]; 
    ... 
+0

Objective-C **는 ** 도트 구문을 사용하여 속성에 액세스합니다. 그리고 그것은'self.string = nil;'또는'[string release];만이 dealloc에 ​​있습니다. 전자는 속성을 통해, 나중에 연결된 인스턴스 변수를 통해 해제됩니다. – DarkDust

+0

나는 그것을 말하지 않았다. 나는 인스턴스 변수에 접근하기 위해 '도트 구문'을 사용하지 않는다고 말했다. 이것은 매우 다르다. 또한 dealloc의 self.string = nil은 좋지 않습니다. – hooleyhoop

+0

문단 구문과 관련하여 문단을 다시 읽으면서 나는 당신이 쓴 것을 잘못 해석했다. 나는 그것을 오도하는 것으로 안다. 나는 dealloc의 속성에 할당하는 것이 좋지 않다는 말을 결코 들어 보지 못했습니다. 왜 이것이 나쁜 생각 일지에 대해 저를 계몽 해주십시오. – DarkDust

0

를 사용하여 초기화 방법에 사실이다.

대신 당신이 anotherString을 해제하는 경우에도 메모리 누수에서 문자열을 방지 할 수 유지의 복사를 사용하여 .H 파일

 
@property (readwrite, copy) NSString *string; 

이 추가.