2012-05-07 3 views
0

다음 코드 조각이 있습니다.이 속성이있는 iVar가 유지되고 그 코드가 dealloc 메서드로 릴리스되었습니다. iVar는 2 가지 방법으로 사용되며 지속적으로 값을 변경하지만 값이 손상된 경우 가끔 사용합니다. 왜 그런가요?, 그것은 EXC_BAD_ACCESS와 코드Mememory Corruption in @property

[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX]; 

이 줄을 충돌 : 루프 방법을 업데이 트를 호출 할 때

@interface ChatController : NSObject <ASIHTTPRequestDelegate>{ 
NSTimer *timer; 
NSString *_idLastMessageFromServer; 
} 

@property(nonatomic, retain)NSString *idLastMessageFromServer; 
@end 

하는 .m

@implementation ChatController 

@synthesize idLastMessageFromServer = _idLastMessageFromServer; 

- (void)initLoopTimer{ 
timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(update:) userInfo:nil repeats:YES]; 
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 
} 

- (void)update:(id)sender{ 
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:CONSTANT_YYYY]; 
[request setDelegate:self]; 
[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX]; 
[request setDidFinishSelector:@selector(requestUpdateFinish:)]; 
[request startAsynchronous]; 
} 

- (void)requestUpdateFinish:(ASIHTTPRequest *)request{ 
NSString *response = [request responseString]; 
if(response && response.length){ 
    if(![response isEqualToString:CHAT_RESPONSE_NO_MESSAGES]){ 
     NSArray *array = [response componentsSeparatedByString:CHAT_PARSE_RESPONSE]; 
     if(array && [array count] == 2){ 
      **_idLastMessageFromServer = [array objectAtIndex:0];** 
     } 
    } 
    } 
} 

그러나이 .H

메시지,하지만 왜?

+0

사람들이 메모리 손상을 검색 할 때 도움이되도록 제목의 철자를 수정해야합니다. – Cthutu

+0

감사합니다 @ Jacky Boy – NTTake

답변

3

self.idLastMessageFromServer 대신 _idLastMessageFromServer을 사용하면 문자열이 유지되지 않습니다. 이것은 객체를 할당 해제하는 유지 횟수를 0으로 떨어 뜨리는 것을 허용합니다. 그 시점에서 나쁜 메모리에 대한 참조를 가지므로 앱이 다운됩니다.

정당한 이유가없는 경우 (-init 또는 -dealloc와 같은 경우) iVars를 직접 사용하지 마십시오. 대신 속성을 사용하십시오. 내가 속성에 대한 자세한 설명을 좀 더 추가 할 것입니다

self.idLastMessageFromServer = [array objectAtIndex:0]; 

[request addPostValue:self.idLastMessageFromServer forKey:CONSTANT_XXX]; 

.

self.idLastMessageFromServer은 속성 값을 읽을 때 자동 생성 된 메서드 -idLastMessageFromServer을 호출합니다.

속성의 값을 설정하는 데 사용
- (NSString *)idLastMessageFromServer 
{ 
    return _idLastMessageFromServer; 
} 

self.idLastMessageFromServer이 방법 -setIdLastMessageFromServer:를 생성 자동 호출 :이 방법은 같을 것입니다.

- (void)setIdLastMessageFromServer:(NSString *)idLastMessageFromServer 
{ 
    if (_idLastMessageFromServer != idLastMessageFromServer) { 
     [_idLastMessageFromServer release]; 
     _idLastMessageFromServer = idLastMessageFromServer; 
     [_idLastMessageFromServer retain]; 
    } 
} 

마지막으로 참고 :이 방법은 같이 보일 것이다 -dealloc 방법에 _idLastMessageFromServer을 해제해야합니다. 같은 뭔가 : 속성과 인스턴스 변수에 대한

- (void)dealloc 
{ 
    [_idLastMessageFromServer release]; 
    [super dealloc]; 
} 

자세한 내용.

속성 (예 : 자기.idLastMessageFromServer)는 getter 및 setter 메서드를 처리하기위한 간단한 방법입니다. 메소드이기 때문에 데이터를 보유 할 수 없습니다. iVars (_idLastMessageFromServer와 같은)는 메모리에있는 위치에 대한 포인터입니다. 단순히 포인터 일 뿐이므로 액세스를 제어하고 상태를 유지할 수 없습니다.

속성과 iVars가 함께 작동합니다.

라인 @property(nonatomic, retain) NSString *idLastMessageFromServer;은 내 구현에서 어딘가에서 클래스는 idLastMessageFromServer 속성에 대한 getter와 setter를 가질 것이라고 말합니다.

라인 @synthesize idLastMessageFromServer = _idLastMessageFromServer;은 iVar _idLastMessageFromServer를 사용하여 idLastMessageFromServer에 대한 getter 및 setter 메소드를 자동으로 생성합니다.

요약하면이 속성은 iVar에 대한 액세스를 제어합니다. iVar은 속성의 저장 위치입니다.

+0

지금 당장 시도해 보겠다. 그렇다면 내가 왜 @synthesize idLastMessageFromServer = _idLastMessageFromServer; _idLastMessageFromServer는 self.idLastMessageFromServer와 같거나 틀린가요? – NTTake

+0

아니야. _idLastMessageFromServer는 변수입니다. self.idLastMessageFromServer는 -idLastMessageFromServer 또는 -setIdLastMessageFromServer :([선언 된 속성] (https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html 참조)에 대한 메소드 호출입니다.)) –

+0

Thanks @ Jeffery Thomas하지만 _idLastMessageFromServer를 사용해야하는 이유가 있다면 왜 속성 만 사용하면 iVar를 만들어야하는지 (self.idLastMessage). 왜 @property (nonatomic, retain) NSString * idLastMessageFromServer;를 선언하고 더 나은'@synthesize idLastMessageFromServer;'를 선언하고 iVar를 사용하지 않기 때문에'NSString * _idLastMessageFromServer;'와'@synthesize idLastMessageFromServer = _idLastMessageFromServer; _idLastMessageFromServer'입니다. – NTTake

5

이 줄 :

_idLastMessageFromServer = [array objectAtIndex:0]; 

아마

self.idLastMessageFromServer = [array objectAtIndex:0]; 

이 따라서 할당 동안 유지/해제를 트리거하는 대신 직접 변수의 속성에 액세스 할 수 있어야합니다. 그렇지 않으면 포인터가 할당되지만 배열에서 가져온 객체가 유지되지 않으면 빠르게 유효하지 않게되고 해제 된 객체를 가리키는 포인터가 남아있게됩니다.

+0

지금 당장 시도해 보겠습니다. 그렇다면 내가 왜 @synthesize idLastMessageFromServer = _idLastMessageFromServer; _idLastMessageFromServer는 self.idLastMessageFromServer와 같거나 틀린가요? – NTTake

+0

아니요, 동일하지 않습니다. _idLastMessageFromServer는 실제 포인터이지만 self.idLastMessageFromServer는 retain을 수행하는 일부 코드의 구문 설탕입니다. 나는 그것이'if (nil! = _x) {[_x release]; } _x = newValue; [_x retain]; ' – craigmj

+0

@craigmj 감사 합니다만, _idLastMessageFromServer를 사용해야하는 이유가 있다면 왜 속성 만 사용하면 iVar를 만들어야하는지 (self.idLastMessage). – NTTake