0

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

在主表视图控制器中,我覆盖了为 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;

米:

@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";

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

谁能解释为什么这会崩溃,并可能给我一些关于如何修复它的指示?我真的不明白为什么 [hostedZoneID release] 会释放 zoneID

4

1 回答 1

0

Route53GetHostedZoneRequest你应该有:

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

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


您的其他问题...

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

当您使用字符串文字时,它是一种特殊类型的对象,它不会真正被保留或释放,因此您可以绕过该问题。

于 2013-07-15T22:33:42.927 回答