UIViewControllerがコンテナーコントローラーにプッシュされ、その後ポップオフされます。割り当てツールを使用すると、View Controllerがその後破棄されることがわかります。ただし、コントローラーのdeallocのブレークポイントに到達することはありません。 deallocが呼び出されない理由を知っている人はいますか? ARCがdeallocを呼び出さずにオブジェクトを破棄することは可能ですか?
また、NSZombiesを無効にしました(deallocが起動しない可能性があると言っている人もいます)。
編集:
Deallocはあまり機能せず、コンソールに出力するだけで、呼び出されることはありません。
- (void)dealloc { NSLog(@"Deallocating..."); }
コンテナーコントローラーを投稿することはできません。これは独自のもので、複雑すぎます。 Deallocは、一部のコントローラーでは一貫して呼び出され、他のコントローラーでは呼び出されません。時間を見つけられたら、問題を再現する簡易版を投稿してみます。
NSZombiesが無効になっていることを確認する方法はありますか?
Edit2
楽器のスクリーンショットを投稿しています。適切に割り当てを解除しているように見えます。
同様の問題に出くわしました。 「自己」に言及しているブロックはありますか?私は、「自己」に言及しているinitで通知を監視するためのブロックをいくつか持っていました。 ARCでは、selfはブロックに保持されます。私のdeallocは呼ばれていませんでした、そして、それは私が観察を取り除いていたところでした。
秘Theは、「自己」への__weak(iOS 5+)または__unsafe_unretained(iOS 4.x)参照を作成し、それを使用して自己または_iVars(これらは「自己」も保持される)にアクセスすることですブロック。以下に例を示します。
__unsafe_unretained TableViewController *weakSelf = self;
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
if (weakSelf.tableView) {
[weakSelf.tableView reloadData];
}
}];
私の場合、NSTimer
でした。ターゲットは保持されるため、View Controllerでの作業が完了したらタイマーを無効にする必要があります。
VCによってdeallocが呼び出されていない場合、コードのどこかに循環参照があり、ARCがdeallocを呼び出すのを妨げています。
確認するいくつかの事項:
私のデリゲート宣言が__unsafe_unretainedを利用しなかったとき、私はお尻に挟まれました。
ARCを使用しても、参照カウントを手動で検査できます。
CFIndex rc = CFGetRetainCount((__bridge CFTypeRef)myObj);
コードがメモリサイクルでハングしているかどうかを確実に知ることができます。
私の問題はデリゲートでした。
デリゲートをチェックしてください!デリゲートプロパティには、weak
を指定する必要があります。
_weak var delegate: SomeProtocol?
_
または
@property (weak, nonatomic) id<SomeProtocol> delegate;
ここに別のヒントがあります(私に起こりました):
tl; dr:クラスプロパティだけでなく、クラスインスタンス変数も調べます。コードでインスタンス変数を割り当てていますか?後でnil
に設定していませんか?
ヘッダーファイルに一連のプロパティ(@property (nonatomic, strong)
および@property (nonatomic, weak)
)を持つクラスがありました。これらのプロパティを1つずつコメントアウトして、これによって何かが変わるかどうかを確認しました。それはしませんでした。メインクラスはまだ割り当て解除されていませんでした。そのため、問題はプロパティにありませんでした。
その後、インスタンス変数を確認しました。 UIViewController
で作成した1つのインスタンス変数(viewDidLoad
)がありました。これneverは割り当て解除されました!
この変数を削除したとき、確かに、私のメインクラスはdeallocと呼ばれていました。
したがって、これは割り当て解除されていないため、私のメインクラスも割り当て解除されていません。そのインスタンス変数をプロパティとして移動すると、問題が解決しました。
質問:なぜこれが起こるのかわかりません。オペレーティングシステムは、インスタンス変数よりもクラスのプロパティをより適切に制御できますか?インスタンス変数を含む親クラスが、そのインスタンス変数のためにリリースされないのは少し奇妙に思えます。