7

アプリケーションの重要なポイントでクラッシュが発生しました。ただし、クラッシュはオーバーリリースされた UIView オブジェクト (具体的には UITableView のヘッダー ビュー、この場合は UISearch バー) から発生しているようです。これについての奇妙な点は、それが nib ファイルからインスタンス化されたことです。これがクラッシュです...

Apple がサンプル プロジェクトの 1 つに持っているものと正確に一致するように、nib ファイルをセットアップしました。

ここに画像の説明を入力

また、時間をかけて NSZombieEnabled と Instruments を使用してこれを分析しました。しかし、なぜこれが起こっているのかについては、まだ頭も尻尾もできません。これが保持/解放の組み合わせです....

ここに画像の説明を入力

また、UIView オブジェクトの作成時に公開されるスタック トレース。

ここに画像の説明を入力

このタイプのエラーの一般的な例は、autorelease ブロック内で作成され、out パラメータに割り当てられる NSError オブジェクトです。ただし、UIView で同じ問題が発生するとは思いません。また、コードのどこにも自動解放ブロックが表示されません (メインの実行ループにあるものを保存してください)。この問題を解決する方法について何か考えはありますか?

4

2 に答える 2

1

問題は、通知をリッスンしたり、KVO オブザーバーを追加したりしても、監視オブジェクトの保持カウントが変更されないことです。そして、ビュー/ビューコントローラー/オブジェクトの割り当てを解除した直後に通知が発生するようです。

メソッドを変更して- (void)dealloc、ビュー/ビューコントローラーから通知/KVO オブザーバーを削除できます

通知:

-(void) dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    //if you are not using ARC you also have to write
    //[super dealloc];
}

KVOの場合、キーパスでメソッドを使用します

- (void)removeObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath

乾杯、ニルス

于 2013-11-06T18:47:57.153 に答える
0

あまり情報がありませんが、感想を述べさせてください。

  • @Nielsが言ったように、観測オブジェクトの保持カウントを変更しないため、KVOは非同期でデータを受信するための悪いパターンです
  • 最善の方法は、データを非同期に更新する必要があるテーブル ビューまたはその他のビューを所有するコントローラーにデリゲート バックして安全にプレイすることです。
  • 常にデリゲート コントローラーを処理し、すべての非同期データを受信する前に自動解放されるのを防ぎます。ポップされたコントローラーをコレクション プロパティに追加するなどしてください。それが機能する
  • もちろん、UINavigationControllerDelegate を使用して、コントローラー デリゲートが解除されたときに非同期転送操作をキャンセルすることもできます。
于 2013-11-05T08:16:45.753 に答える