0

私のメモリ管理とスレッド化の知識は非常に限られているので、本当に基本的なものが欠けている可能性があります。この問題の回避策を見つけましたが、何が起こっているのかわからないのが本当に気になります。

2つの非同期HTTPリクエストを作成するクラスがあります。1つはXML構成ファイル用で、もう1つは画像用です。同じクラスで2つの非同期リクエストが実行されているため、同じNSURLConnectionDelegateメソッドを再利用しています(おそらく要因)。まず、構成ファイルを非同期でフェッチし、ととして保存されている2つのURLを抽出しsponsorImageますsponsorUrl。次に、の値を使用してsponsorImage画像データを非同期にフェッチします。sponsorUrlただし、イメージを取得した後(2番目の非同期イベントが完了した後)にリリースされていることがわかりました。

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]たが、違いはありません。動作する唯一のことは、2番目の要求を行う前に変数に「触れる」ことです。

私は何が欠けていますか?

4

2 に答える 2

2

便利なコンストラクターを使用しているため、変数は自動解放されます! alloc、copy、new などのメソッドを使用している場合にのみ、暗黙的に保持されます。

次に、sponsorUrl = .... と書くことで、生成されたセッターではなく、生成されたインスタンス変数を使用しています。self.sponsorUrl = @"Blah"; と書く必要があります。または [self setSponsorUrl:@"blah"] セッターに変数を保持させるために。

于 2012-04-27T09:24:03.450 に答える
1

確かに、メモリ管理に問題があるようです。

変数を使用する完全なコードを提供していないため、何が起こっているのかを説明するのはかなり困難です。例として、次のステートメントを取り上げます。

sponsorUrl = [sponsorUrl stringByAppendingString:@""];

あなたがすることはsponsorURL、新しい値を割り当てることです。古い値(最初に変数を初期化したもの、つまり、retainあなたが言及したもの)が解放されます(stringByAppendingString新しいオブジェクトを偽造します)。指し示す新しいオブジェクトsponsorURLは、自動解放されたオブジェクトであり、その有効期間は正確にはわかっていません。ある時点で (おそらく次のメイン ループの繰り返しで) 解放されることしかわかりません。したがって、変数に「触れる」ことで、変数に触れた時点から始まる寿命を持つ新しい値を変数に割り当てることになります...いずれにせよ、かなり信頼できません。

私の提案は次のとおりです。

  1. クラスで 2 つのプロパティを定義して、 と を処理sponsorURLsponsorImageます。

  2. それらをそのretain種類にします。

  3. それらのアクセサ メソッド、つまり self.sponsorURL = [...] を介してのみ値を割り当てます。

  4. プロパティに割り当てるすべてのオブジェクトがオブジェクトであることを確認してくださいautoreleased(または、割り当てを解放します)。

より多くのコードを提供していただくと、より徹底的にレビューすることが可能になりますが、上記のガイドラインに従えば、まったく問題はありません (約...)

于 2012-04-27T09:25:45.543 に答える