我创建了一个调用Web服务的图形应用程序。用户可以放大图形的移动范围,程序偶尔会决定调用Web服务以获取更多数据。这是通过以下过程实现的:Objective-C内存管理问题
该图具有呈现循环,该循环不断呈现图形,以及将Web服务调用信息添加到堆栈的一些决策逻辑。
单独的线程从堆栈中获取最新的Web服务调用信息,并使用它来进行Web服务调用。堆栈中的其他对象被分类。
这样做的想法是将Web服务调用的数量减少到仅适用的那些,并且一次只有一个。
权,与长故事的方式进行(对此我表示歉意),这里是我的内存管理问题:
有图有持续性(和适当锁定)的NSDate *当前显示的对象开始&图表的结束时间。这些传递给我的Web服务请求对象的初始化程序。 Web服务调用对象然后保留日期。
Web服务调用完成后(或者如果它们已过期,则为binned),它们释放NSDate *。
该图本身在“触摸已结束”事件中释放并重新分配新的NSDates *。
如果在调用removeAllObjects时堆栈上只有一个Web服务调用对象,则在Web服务调用对象的释放方法尝试释放日期对象时发生EXC_BAD_ACCESS(即使它们看起来存在且处于作用域中在调试器中)。
但是,如果我从析构函数注释掉释放消息,则释放堆栈上的一个对象时不会发生内存泄漏,但如果堆栈中有多个对象,则会发生内存泄漏。
我完全不知道怎么回事。它没有什么区别我用于Web服务调用对象的存储语义,因为它们是在初始化程序中分配的,然后才被读取(所以为了正确性而设置为只读)。
如果我在初始化程序中保留或复制日期(尽管其他任何明显超出范围或在别处释放并导致崩溃),似乎也没有什么区别。
对不起,这个解释很长,我希望它已经足够清晰,但我不是在赌博,或者我害怕。非常感谢任何能提供帮助的人,甚至提出我可能错过的任何事情?
要明确希望事情了一下,这里是一些伪(ISH)代码...东西(不包括锁和initialisers):
NSMutableArray* requests;
NSDate* start, end;
-(void)webServiceThread
{
if([requests count] > 1)
{
[self doRequestWithParams:[requests lastObject]];
[requests removeAllObjects];
}
}
-(void)render
{
if(conditions for another web service call are met)
{
WebServiceRequest* new = [[WebServiceRequest alloc] initWithDates:start :end];
[requests addObject:new];
[new release];
}
[self doRendering];
}
-(void)touchesEnded
{
[start release];
[end release];
start = [[NSDate dateSinceTimeInterval:chartLeft] retain]; //Ficticious NSDate Method names for example.
end = [[NSDate dateSinceTimeInterval:chartRight] retain];
}
然后在Web服务调用对象:
NSDate* startDate;
NSDate* endDate;
-(void)initWithDates:start :end
{
startDate = [start retain];
endDate = [end retain];
}
-(void)dealloc
{
[super dealloc];
//The following two lines cause EXC_BAD_ACCESS if this is the only object on the request stack. If they are commented, however, memory is leaked if this is not the only object on the request stack.
[startDate release];
[endDate release];
}
这听起来像是有一个释放到很多。从你的解释来看,这听起来像是这个额外释放发生的地方并不明显。我想在某种程度上autorelease必须偷偷溜进去,你错过了。如果您可以发布相关代码 - 所有作业,保留和发布日期,这将有所帮助。 – 2010-04-22 13:49:57
作为一个小提示,尽管不需要,在'dealloc'中最后调用'[super dealloc]'最后通常更安全。 http://stackoverflow.com/questions/909856/why-do-i-have-to-call-super-dealloc-last-and-not-first – 2010-04-22 13:58:44
感谢您的回复,已添加伪代码(实际代码是大量的更长;也可能是问题的一部分)。自动释放的想法没有发生在我身上,但是在适用的情况下,所有东西都有一个存储方法(目前保留)。 – Tobster 2010-04-22 13:58:58