2012-05-07 30 views
0

我有下一段代碼,一個帶有此屬性的iVar保留並在其類dealloc方法中發佈。 iVar在2種方法中使用,並且不斷更改該值,但有時會在使用該值時損壞 。這是爲什麼?@property中的MeMemory腐敗

@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:,它在這行代碼

[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX]; 

與EXC_BAD_ACCESS崩潰消息,但爲什麼?

+0

您應該更正標題的拼寫,以幫助人們搜索內存損壞。 – Cthutu

+0

謝謝@Jacky Boy – NTTake

回答

3

通過使用_idLastMessageFromServer而不是self.idLastMessageFromServer,您不保留字符串。允許保留計數下降到零,從而釋放對象。在那個時候,你有一個壞內存的參考,因此該應用程序崩潰。

除非您有充足的理由(如-init或-dealloc),否則請勿直接使用iVar。改用該屬性。

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

self.idLastMessageFromServer = [array objectAtIndex:0]; 

我將添加更多一點的詳細解釋有關屬性。

self.idLastMessageFromServer當用於讀取屬性的值時調用自動生成的方法-idLastMessageFromServer。這種方法看起來像:

- (NSString *)idLastMessageFromServer 
{ 
    return _idLastMessageFromServer; 
} 

用於設置屬性的值時self.idLastMessageFromServer調用生成的方法-setIdLastMessageFromServer:的汽車。這種方法看起來像:

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

最後一點:一定要釋放_idLastMessageFromServer在-dealloc方法。喜歡的東西:

- (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

謝謝@Jeffery Thomas,但如果有爲什麼使用_idLastMessageFromServer diferente爲什麼需要創建一個iVar如果只使用該屬性(self.idLastMessage)。爲什麼需要聲明'NSString * _idLastMessageFromServer;'和'@synthesize idLastMessageFromServer = _idLastMessageFromServer;'因爲不僅聲明'@property(nonatomic,retain)NSString * idLastMessageFromServer;'更好和'@synthesize idLastMessageFromServer;'不使用iVar' _idLastMessageFromServer'。 – NTTake

5

這條線:

_idLastMessageFromServer = [array objectAtIndex:0]; 

可能應該是

self.idLastMessageFromServer = [array objectAtIndex:0]; 

這將訪問,而不是直接變量的性質,從而觸發所述分配期間的保留/釋放。否則,指針將被分配,但從數組中取出的對象不會被保留,它可能會很快變爲無效,並且剩下一個指向已釋放對象的指針。

+0

現在我要去試試它,但是如果你的權利爲什麼這是因爲當我做@synthesize idLastMessageFromServer = _idLastMessageFromServer; _idLastMessageFromServer與self.idLastMessageFromServer是否相同? – NTTake

+0

不,不一樣。 _idLastMessageFromServer是實際的指針,而self.idLastMessageFromServer是一些保留的代碼的語法糖。我認爲它就像'if(nil!= _x){[_x release]; } _x = newValue; [_x retain];' – craigmj

+0

謝謝@craigmj,但是如果有爲什麼使用_idLastMessageFromServer的話,爲什麼只需要使用屬性(self.idLastMessage)就需要創建一個iVar。 – NTTake