我的记忆管理和线程知识非常有限,所以我可能会遗漏一些非常基本的东西。我找到了解决这个问题的方法,但是我真的很困扰我,我看不到发生了什么。
我有一个类,它产生两个异步HTTP请求,一个用于XML配置文件,另一个用于图像。因为在同一个类中有两个异步请求,我正在重用相同的NSURLConnectionDelegate
方法(可能是因子)。我首先异步获取配置文件并提取两个URL,存储为sponsorImage
和sponsorUrl
。然后我使用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]
,但它没有什么区别。唯一有效的方法是在发出第二个请求之前“触摸”变量。
我错过了什么?
答案 0 :(得分:2)
当你使用便利构造函数时,变量是自动释放的!只有在使用alloc,copy或new等方法时,才会隐式保留它们。
其次,通过编写sponsorUrl = ....您不是使用生成的setter而是使用生成的实例变量。你需要写self.sponsorUrl = @“Blah”;或[self setSponsorUrl:@“blah”]以使setter保留变量。
答案 1 :(得分:1)
事实上,您似乎在内存管理方面存在一些问题。
很难解释发生了什么,因为您没有提供使用变量的完整代码。举个例子,请接受声明:
sponsorUrl = [sponsorUrl stringByAppendingString:@""];
您所做的是为sponsorURL
分配一个新值;旧值(首先用变量初始化变量的值,即你提到的变量retain
)被释放(stringByAppendingString
伪造一个新对象); sponsorURL
指向的新对象是一个自动释放的对象,其生命周期并不完全为人所知:我们只知道在某些时候它将被释放(可能在下一个主循环迭代中)。因此,通过“触摸”变量,您将为其分配一个新值,其寿命从您触摸变量的点开始......在任何情况下都非常不可靠。
我的建议如下:
在您的班级中定义两个属性来处理sponsorURL
和sponsorImage
;
制作retain
种;
仅通过其访问者方法为其赋值,即self.sponsorURL = [...]
确保您分配给属性的任何对象都是autoreleased
个对象(否则,请使用分配执行发布)。
如果您提供更多代码,那么可以更全面地查看它,但如果您遵循上述指导原则,您将完全没有问题(约...)