0

2つのViewControllerがあります。1つはボタンのグリッドがあり、もう1つはユーザーが押したボタンに基づく詳細な説明です。

Instruments割り当てツールで「MarkHeap」を使用していますが、ユーザーが詳細なView Controllerを確認し、ナビゲーションバーの戻るボタンを押した後、アプリのメモリが増加していることがわかりました。ITの結果、メモリの正味の変化はゼロになるはずです...私はARC、xcode 4.2.1を使用しており、iOS5.0以降にデプロイしています

ボタンを押した後に新しいViewControllerをロードすると、いくつかのデータ画像がバックグラウンドスレッドにロードされます。戻るボタンをすばやく押しているために、そのデータがまだバックグラウンドスレッドに読み込まれていて、メモリから解放されない可能性はありますか?

4

1 に答える 1

0

私が持っていたクラスのスライドから、あなたが直面している可能性のあるメモリサイクルの問題について説明しました。

クラスの次のプロパティがある場合はどうなりますか?

@property (strong, nonatomic) NSArray* myBlocks;    // array of blocks

次に、そのクラスのメソッドの1つで次のことを実行しようとしましたか?

[self.myBlocks addObject:^() {
    [self doSomething];
}];

ブロック内で参照されるすべてのオブジェクトは、ブロックが保持している限り、ヒープ内に留まります。(言い換えると、ブロックは、ブロック内で参照されるすべてのオブジェクトへの強力なポインターを保持します。)

この場合、selfはこのブロックで参照されるオブジェクトです。したがって、ブロックには自己への強力なポインタがあります。ただし、selfにもブロックへの強力なポインタがあることに注意してください(myBlocksプロパティを介して)

これは深刻な問題です!

現在、自己もブロックもヒープから逃れることはできません。それは、それらの両方(互いのポインター)への強力なポインターが常に存在するためです。これはメモリの「サイクル」と呼ばれます。

解決:

ローカル変数は常に強力です。それは大丈夫です。スコープから外れると消えて、強いポインタが消えてしまうからです。しかし、ローカル変数が弱いことを宣言する方法があります。方法は次のとおりです...

__weak MyClass* weakSelf = self;
[self.myBlocks addObject:^{
    [weakSelf doSomething];
}];

これで問題が解決します。これは、ブロックに自分自身への弱いポインタしかないためです。(自己はまだブロックへの強力なポインターを持っていますが、それは大丈夫です)大学の誰かがこの自己への強力なポインターを持っている限り、ブロックのポインターは良いです。そして、自己が存在しない場合(myBlocksが存在しないため)、ブロックは存在しないため、すべてが順調です。

于 2012-07-20T00:03:16.377 に答える