0

アプリがバックグラウンドに移行すると、View Controller クラスの割り当てが解除されます。ARCを使用しています。

アプリがアクティブになり、メソッドを実行するときに通知をサブスクライブする UIViewController があります。ただし、アプリがバックグラウンドで約 30 秒経過してから再開すると、アプリは「割り当て解除されたインスタンスにメッセージが送信されました」というメッセージでクラッシュします。

Zombie オブジェクトを有効にすると、View Controller 自体が Zombie であることがわかります。

ありがとうございました!

View Controller のインスタンス化 (AppDelegate 内):

UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];

AppDelegate のフォアグラウンド通知:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationForegrounded object:self];
}

ビュー コントローラーのフォアグラウンド通知:

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeForeground) name:kNotificationForegrounded object:nil];
}

AppDelegate で強い参照を作成しようとしましたが、View Controller の割り当てが解除されます。

@property (strong, nonatomic) MyViewController *myViewController;

View Controllerを配列に追加して、AppDelegaeの配列への強い参照を試みましたが、それでも同じ結果が得られます:

@property (strong, nonatomic) NSMutableArray *viewControllers;
//...
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
MyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];
self.viewControllers = [[NSMutableArray alloc] init];
[self.viewControllers addObject:myViewController];
4

2 に答える 2

1

ここには 2 つの問題があります。アプリ デリゲートがオブジェクトの所有権を正しく管理していないことと、View Controller がそれ自体をクリーンアップしていないことです。

コードを実行して をインスタンス化するたびに、新しいインスタンスMyViewControllerに置き換えることで、既存のすべてのビュー コントローラーの所有権を解放します。self.viewControllers一度だけ割り当て、必要に応じてオブジェクトを追加および削除します。また、強力なプロパティを使用することはなく、同じ名前のローカル インスタンス変数のみを使用します。おそらく、このコードを何度も実行したいことを実際に確認する必要があります(説明した症状と情報を考えると、そうであると思います)。

また、 でMyViewController、次を実装しますdealloc(または、既に実装している場合は追加します)。

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
于 2013-03-20T16:29:55.073 に答える
0

問題:

  1. MyViewControllerMyViewController *myViewController = [storyBoard instantiateViewControllerWithIdentifier:@"MyViewController"];が呼び出されるたびに再インスタンス化されました。

  2. ARC を使用すると、アプリがフォアグラウンドに移動すると、何らかのクリーニングが行われるように見えます。

  3. アプリがフォアグラウンドに移動され、@deallocフォアグラウンド通知が 2 つの異なるスレッドから同時に呼び出されたため、通知でセレクター メソッドが実行されたときに、(参照なしの) ビュー コントローラーは既にマークされているか、割り当て解除される予定でした。

ソリューション:

@Carl が示唆したように、ビュー コントローラーの使用が完了した時点でなく、以前の時点で[[NSNotificationCenter defaultCenter] removeObserver:self];追加しました。@dealloc再インスタンス化の直前にそれを行うこともうまくいくと思います。

于 2013-03-21T17:57:21.733 に答える