I have the next piece of code, one iVar with this property retained and released in it’s class dealloc method. The iVar is used in 2 methods and continually change the value but
sometimes when I use the value is corrupted. Why is that?
.h
@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];**
}
}
}
}
But when the loop calls the method update:, it crashes in this line of code
[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX];
with EXC_BAD_ACCESS message, but why?
By using
_idLastMessageFromServerinstead ofself.idLastMessageFromServer, you are not retaining the string. The allows the retain count to drop to zero which deallocates the object. At that point you have a reference to bad memory, hence the app crashes.Don’t use iVars directly unless you have a good reason (like -init or -dealloc). Use the property instead.
and
I’ll add a bit more of a detailed explanation about properties.
self.idLastMessageFromServerwhen used to read the value of the property calls an auto generated method-idLastMessageFromServer. This method will look something like:self.idLastMessageFromServerwhen used to set the value of the property calls an auto generated method-setIdLastMessageFromServer:. This method will look something like:One final note: be sure to release _idLastMessageFromServer in your
-deallocmethod. Something like:More details about properties and iVars.
Properties (like self.idLastMessageFromServer) are simply a easy way to handle getter and setter methods. They cannot hold data because they are methods. iVars (like _idLastMessageFromServer) are a pointer to a location in memory. They cannot control access and maintain state because they are simply a pointer.
Properties and iVars work together.
The line
@property(nonatomic, retain) NSString *idLastMessageFromServer;says that somewhere in my implementation, my class will have a getter and setter for the property idLastMessageFromServer.The line
@synthesize idLastMessageFromServer = _idLastMessageFromServer;auto generates the getter and setter methods for idLastMessageFromServer using the iVar _idLastMessageFromServer.In short, the property controls access to the iVar; the iVar is the storage location for the property.