我有下一段代码,一个保留了此属性的iVar并在其类dealloc
方法中发布。 iVar用于2种方法并不断改变值
有时当我使用该值时已损坏。那是为什么?
·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];**
}
}
}
}
但是当循环调用方法更新:时,它会在这行代码中崩溃
[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX];
有EXC_BAD_ACCESS消息,但为什么?
答案 0 :(得分:5)
这一行:
_idLastMessageFromServer = [array objectAtIndex:0];
应该是
self.idLastMessageFromServer = [array objectAtIndex:0];
这将直接访问属性而不是变量,从而在赋值期间触发保留/释放。否则,指针被指定,但是从数组中取出的对象不会被保留,它可能很快变为无效,并且您将留下指向已释放对象的指针。
答案 1 :(得分:3)
使用_idLastMessageFromServer
代替self.idLastMessageFromServer
,您不会保留字符串。允许保留计数降至零,从而释放对象。那时你有一个坏内存的引用,因此应用程序崩溃。
除非你有充分的理由(比如-init或-dealloc),否则不要直接使用iVars。请改用该属性。
[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];
}
}
最后一点:确保在-dealloc
方法中发布_idLastMessageFromServer。类似的东西:
- (void)dealloc
{
[_idLastMessageFromServer release];
[super dealloc];
}
有关属性和iVars的更多详细信息。
属性(如self.idLastMessageFromServer)只是处理getter和setter方法的简单方法。他们无法保存数据,因为它们是方法。 iVars(如_idLastMessageFromServer)是指向内存中某个位置的指针。他们无法控制访问和维护状态,因为它们只是一个指针。
属性和iVars协同工作。
行@property(nonatomic, retain) NSString *idLastMessageFromServer;
表示在我的实现中的某个地方,我的类将为属性idLastMessageFromServer设置一个getter和setter。
行@synthesize idLastMessageFromServer = _idLastMessageFromServer;
使用iVar _idLastMessageFromServer自动为idLastMessageFromServer生成getter和setter方法。
简而言之,该物业控制着对iVar的访问; iVar是酒店的存储地点。