0

我有下一段代码,一个具有此属性的 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];**
        }
     }
   }
}

但是当循环调用方法update:时,它在这行代码中崩溃了

[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX];

带有 EXC_BAD_ACCESS 消息,但为什么呢?

4

2 回答 2

5

这一行:

_idLastMessageFromServer = [array objectAtIndex:0];

应该是

self.idLastMessageFromServer = [array objectAtIndex:0];

这将直接访问属性而不是变量,从而在分配期间触发保留/释放。否则,指针被分配,但从数组中取出的对象不会被保留,它可能很快就会变得无效,并且你会留下一个指向已释放对象的指针。

于 2012-05-07T14:29:20.310 回答
3

通过使用_idLastMessageFromServer而不是self.idLastMessageFromServer,您不会保留字符串。允许保留计数降至零,从而解除分配对象。那时你有一个对坏内存的引用,因此应用程序崩溃了。

不要直接使用 iVar,除非你有充分的理由(如 -init 或 -dealloc)。改为使用该属性。

 [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];
}

有关属性和 iVar 的更多详细信息。

属性(如 self.idLastMessageFromServer)只是处理 getter 和 setter 方法的简单方法。它们不能保存数据,因为它们是方法。iVar(如 _idLastMessageFromServer)是指向内存中某个位置的指针。它们无法控制访问和维护状态,因为它们只是一个指针。

属性和 iVar 一起工作。

该行@property(nonatomic, retain) NSString *idLastMessageFromServer;说在我的实现中的某个地方,我的类将具有属性 idLastMessageFromServer 的 getter 和 setter。

该行@synthesize idLastMessageFromServer = _idLastMessageFromServer;使用 iVar _idLastMessageFromServer 自动为 idLastMessageFromServer 生成 getter 和 setter 方法。

简而言之,该属性控制对 iVar 的访问;iVar 是属性的存储位置。

于 2012-05-07T14:34:46.960 回答