由于属性被释放,detailViewController使用arc在dealloc上崩溃

时间:2013-07-15 22:21:10

标签: ios objective-c cocoa

在导航视图控制器中使用后退按钮时,我遇到了视图控制器崩溃的问题。

在主表视图控制器中,我重写了如下所示的segue准备:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

/*
 When a row is selected, the segue creates the detail view controller as the destination.
 Set the detail view controller's detail item to the item associated with the selected row.
 */
if ([[segue identifier] isEqualToString:@"getHostedZoneSegue"]) {

    NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
    GetHostedZoneViewController *detailViewController = [segue destinationViewController];
    NSLog(@"setting zone ID");

    detailViewController.zoneID = [hostedZonesListID objectAtIndex:selectedRowIndex.row];

}
}

GetHostedViewController具有声明的属性zoneID:

@interface GetHostedZoneViewController : UIViewController 
{
    NSString *zoneID;
}
@property (nonatomic, copy)   NSString *zoneID;

在viewDidLoad中我对框架中的方法执行此调用(对框架的调用发生在GCD异步块中,框架不使用ARC):

Route53GetHostedZoneRequest *request = 
[[Route53GetHostedZoneRequest alloc] initWithHostedZoneID:self.zoneID];

框架做到了这样的事情: .H:

@interface Route53GetHostedZoneRequest : AmazonServiceRequestConfig
{
    NSString *hostedZoneID;
}
@property (nonatomic, copy) NSString *hostedZoneID;

的.m:

@synthesize hostedZoneID;

-(id)initWithHostedZoneID:(NSString *)theHostedZoneID
{
    if (self = [self init]) {
        hostedZoneID = theHostedZoneID;
    }
    return self;
}

应用程序中的下一个调用是使用前一个调用的结果在框架中的另一个类中使用不同的方法:

Route53GetHostedZoneResponse *response = [[AmazonClientManager r53] getHostedZone:request];

当这个完成后,请求和响应都被释放(正如预期的那样),奇怪的是当请求被释放时它也会释放zoneID。使用工具我跟踪了违规版本:

[hostedZoneID release];

在Route53GetHostedZoneRequest.m的dealloc方法中。

当回到主控制器后释放GetHostedZoneViewController并导致应用程序崩溃时,这会导致僵尸。

如果我设置

detailViewController.zoneID = @"somestring";

无论我来回走动多少次,该应用都不会崩溃。

任何人都可以解释为什么会崩溃并且可能会给我一些关于如何修复它的指示?我真的不明白为什么zoneID由[hostedZoneID release]

发布

1 个答案:

答案 0 :(得分:0)

Route53GetHostedZoneRequest你应该:

- (id)initWithHostedZoneID:(NSString *)theHostedZoneID
{
    if (self = [self init]) {
        self.hostedZoneID = theHostedZoneID;
    }
    return self;
}

因为否则您没有保留实例,因为此代码不使用ARC。


您的其他问题......

NSString个实例是不可变的,因此当您在属性上指定copy时,它实际上不会被复制,它只会被保留。因此zoneIDhostedZoneID实际上是同一个实例。

当你使用字符串文字时,它是一种特殊的对象,它不会被保留或释放,因此你可以绕过这个问题。