0

我的内存管理和线程知识非常有限,所以我可能遗漏了一些非常基本的东西。我已经找到了解决这个问题的方法,但它真的非常困扰我,我看不到正在发生的事情。

我有一个类发出两个异步 HTTP 请求,一个用于 XML 配置文件,另一个用于图像。因为在同一个类中有两个异步请求,所以我重用了相同的NSURLConnectionDelegate方法(也许是因素)。我首先异步获取配置文件并提取两个 url,存储为sponsorImagesponsorUrl. 然后我使用 的值sponsorImage来异步获取图像数据。不过,我发现,在我获得图像之后(在第二个异步事件完成之后),sponsorUrl已经发布了。

我意外地发现,sponsorUrl如果我在创建图像请求的方法中“对它做某事”,我可以防止被释放——我的意思是“做某事”。基本上,我的代码如下所示:

- (void) loadImage
{
    sponsorUrl = [sponsorUrl stringByAppendingString:@""];

    NSURL *url = [NSURL URLWithString:sponsorImage];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setValue:dateString forHTTPHeaderField:@"If-Modified-Since"];

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];
    [connection release];   
}

如果我删除此方法的第一行(我在 url 中添加“”),则保留该变量。如果我删除它,它就会被释放。这对我来说毫无意义。

我试过sponsorUrl@propterty (nonatomic, retain);声明 我试过sponsorUrl静态声明;我已经尝试添加[sponsorUrl retain]我设置它的位置,但它没有任何区别。唯一有效的是在发出第二个请求之前“触摸”变量。

我错过了什么?

4

2 回答 2

2

当您使用便利构造函数时,变量是自动释放的!仅当您使用诸如 alloc、copy 或 new 之类的方法时,它们才会被隐式保留。

其次,通过编写赞助商Url = ...。您不是使用生成的setter,而是使用生成的实例变量。你需要写 self.sponsorUrl = @"Blah"; 或 [self setSponsorUrl:@"blah"] 以便让 setter 保留变量。

于 2012-04-27T09:24:03.450 回答
1

确实,您似乎在内存管理方面遇到了一些问题。

很难解释发生了什么,因为您没有提供使用变量的完整代码。举个例子,拿下面的语句:

sponsorUrl = [sponsorUrl stringByAppendingString:@""];

您所做的是分配sponsorURL一个新值;旧值(你首先初始化变量的那个,即retain你提到的那个)被释放(stringByAppendingString伪造一个新对象);指向的新对象sponsorURL是一个自动释放的对象,其生命周期并不完全清楚:我们只知道它会在某个时候被释放(可能在下一次主循环迭代时)。因此,通过“触摸”变量,您正在为其分配一个新值,该值的生命周期从您触摸变量的点开始......无论如何都是非常不可靠的。

我的建议如下:

  1. 在你的类中定义两个属性来处理sponsorURLsponsorImage;

  2. 使他们成为retain那种人;

  3. 仅通过它们的访问器方法为它们赋值,即 self.sponsorURL = [...]

  4. 确保您分配给属性的任何对象都是autoreleased对象(或者,使用分配进行释放)。

如果您提供更多代码,则可以更彻底地审查它,但如果您遵循上述指南,您将完全没有问题(大约...)

于 2012-04-27T09:25:45.543 回答