0

ナビゲーション ビュー コントローラーで [戻る] ボタンを使用すると、ビュー コントローラーがクラッシュするという問題があります。

マスター テーブル ビュー コントローラーで、次のようにセグエの準備をオーバーライドしました。

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

何度行ってもアプリがクラッシュしません。

これがクラッシュする理由を説明して、修正方法についてのヒントを教えてもらえますか? [hostedZoneID リリース] によって zoneID がリリースされている理由がよくわかりません

4

1 に答える 1

0

あなたRoute53GetHostedZoneRequestが持っている必要があります:

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

そうしないと、このコードが ARC を使用していないため、インスタンスが保持されないためです。


追加の質問...

NSStringインスタンスは不変であるためcopy、プロパティで指定すると、実際にはコピーされず、保持されるだけです。したがって、zoneIDhostedZoneIDは実際には同じインスタンスです。

文字列リテラルを使用する場合、それは実際には保持または解放されない特別な種類のオブジェクトであるため、問題を回避します。

于 2013-07-15T22:33:42.927 に答える