我对保留数组中的对象有疑问。我正在构建一个框架来与 Amazon Route 53 交互,并尽可能地关注 AWS IOS 开发工具包的其余部分。我正在调用返回 XML 的 Web 服务。来自 Web 服务的响应由 NSXMLParser 委托编组到一个类中。委托切换到另一个委托来处理 XML 的嵌套部分。第二个委托类将嵌套部分解组为第二个类。第二类的对象放在第一类的一个数组中。当第二个委托被释放时,它正在释放对象(不是它们所在的数组,只是对象本身。当响应返回时,所有属性都被填充,
这涉及到很多代码,所以我希望从委托中将对象分配给数组有明显的意义。我很确定我在整个过程中都在维护强引用,并且我认为如果将对象添加到数组中,它们将无法/不会从数组中释放,直到数组被释放。
如果您有兴趣查看代码,可在此处获得:
https://bitbucket.org/entr04y/aws-sdk-ios
该应用程序位于示例子目录 (Route53_demo) 中,初始调用位于 ListHostedZonesViewController.m (viewWillAppear) 中。这会调用 src 目录中的 Route53 框架 - AmazonRoute53Client.m,它调用 Route53ListHostedZonesRequestMarshaller.m 作为解组响应的委托。第二个代表是 Route53HostedZoneUnmarshaller.m。
希望有人能指出我遗漏的东西......过去四天我一直在盯着它看,但我无法弄清楚我所做的与以下 AWS 的一些示例代码不同这个相同的模式。
按照下面的要求,我将尝试添加代码的相关部分,因为这样做的方式似乎并不明显:
初始请求是从这样的视图控制器发出的:
Route53ListHostedZonesRequest *request = [[Route53ListHostedZonesRequest alloc] initWithMaxItems:100];
Route53ListHostedZonesResponse *listHostedZonesResponse = [[AmazonClientManager r53] listHostedZones:request];
然后在 AmazonRoute53Client.m (在我的框架中)中处理:
-(Route53ListHostedZonesResponse *)listHostedZones:(Route53ListHostedZonesRequest *)listHostedZonesRequest
{
AmazonServiceRequest *request = [Route53ListHostedZonesRequestMarshaller createRequest:listHostedZonesRequest];
return (Route53ListHostedZonesResponse *)[self invoke:request rawRequest:listHostedZonesRequest unmarshallerDelegate:[Route53ListHostedZonesResponseUnmarshaller class]];
}
响应被发送到 Route53ListHostedZonesResponseUnmarshaller.m 并解析为 Route53ListHostedZonesResponse 类的实例:
-(Route53ListHostedZonesResponse *)response
{
if (nil == response) {
response = [[Route53ListHostedZonesResponse alloc] init];
}
return response;
}
当解析器命中包含托管区域的嵌套部分时,它被委派给另一个解组器 Route53HostedZoneUnmarshaller:
if ([elementName isEqualToString:@"HostedZone"]) {
[parser setDelegate:[[[Route53HostedZoneUnmarshaller alloc] initWithCaller:self withParentObject:self.response.hostedZones withSetter:@selector(addObject:)] autorelease]];
}
(hostedZones 被声明为 NSMutableArray 并且是 Route53HostedZonesResponse 类的非原子保留属性),它将 XML 中的项目放入 XML 中包含的每个托管区域的 Route53HostedZone 实例中:
-(Route53HostedZone *)response
{
if (nil == response) {
response = [[Route53HostedZone alloc] init];
}
return response;
}
在 xml 块的末尾,对象被返回给调用者,如下所示:
if ([elementName isEqualToString:@"HostedZone"]) {
if ( caller != nil) {
[parser setDelegate:caller];
}
if (parentObject != nil && [parentObject respondsToSelector:parentSetter]) {
[parentObject performSelector:parentSetter withObject:self.response];
}
return;
}
在 xml 响应结束时,Route53ListHostedZonesResponse 对象填充如下:
if ([elementName isEqualToString:@"ListHostedZonesResponse"])
{
if (caller != nil) {
[parser setDelegate:caller];
}
if (parentObject != nil && [parentObject respondsToSelector:parentSetter]) {
[parentObject performSelector:parentSetter withObject:self.response];
}
return;
}
至此,AWS 运行时库和 Route53 库完成了对响应的处理,解组器对象、Route53ListHostedZonesResponse 对象和所有 Route53HostedZone 对象都被释放。
回到视图控制器,当我尝试访问 listHostedZoneResponse 中的对象时,所有属性都可用,除了 hostsZones 数组中的对象现在是僵尸。我在 Route53HostedZoneUnmarshaller.m 中覆盖了 dealloc,如下所示:
-(void)dealloc
{
AMZLogDebug(@"deallocating zone object unmarshaller");
// [response release];
// [super dealloc];
}
这会阻止 unmarshaller 被释放并通过扩展 hostsZones 对象,此时代码可以工作(但当然会像筛子一样泄漏) 我怎样才能将 Route53HostedZone 对象放入 hostsZones 数组以便保留它们?