読者です 読者をやめる 読者になる 読者になる

しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

アプリ中断すると NavigatedFrom が起きるけど再開で NavigateTo は起きないらしい

Windows ストアアプリ C# Windows ランタイムアプリ

イベントハンドラは登録しっぱなしにすると解放されなくなってメモリリークの原因となるため、下記のように不要になったタイミングで解除するようなことも多いと思います

public MainPage()
{
    this.InitializeComponent();

    Window.Current.SizeChanged += this.OnSizeChanged;
}

private void OnSizeChanged(object sender, Windows.UI.Core.WindowSizeChangedEventArgs e)
{
    if (Window.Current.Bounds.Width < 500)
    {
        VisualStateManager.GoToState(this, "Narrowed", true);
    }
    else
    {
        VisualStateManager.GoToState(this, "Filled", true);
    }
}

// 概要:
//     Page がアンロードされて親 Frame の現在のソースではなくなった直後に呼び出されます。
//
// パラメーター:
//   e:
//     コードのオーバーライドによって検査できるイベント データ。イベント データは、現在の Page をアンロードしたナビゲーションを示しています。
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

     Window.Current.SizeChanged -= this.OnSizeChanged;
}

上記は Windows のサイズ変更イベントを利用している例ですが、画面を離れる場合に呼び出される OnNavigateFrom メソッド内でイベントの解除を行っています

特に問題ないように見えますが、実はこの OnNavigatedFrom メソッドは画面を離れる場合だけでなく、中断(Suspend)時にも呼び出されます

さらに中断から再開(Resume)した際には対となる OnNavigateTo メソッドは呼び出されません!

何が問題かというと、このままでは中断後に復帰するとイベントハンドラが解除されたままになり、イベント時の処理が行われなくなる点です;

// 概要:
//     Page がアンロードされて親 Frame の現在のソースではなくなった直後に呼び出されます。
//
// パラメーター:
//   e:
//     コードのオーバーライドによって検査できるイベント データ。イベント データは、現在の Page をアンロードしたナビゲーションを示しています。
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    if (e.SourcePageType == this.GetType())
    {
        return;
    }

    Window.Current.SizeChanged -= this.OnSizeChanged;
}

なので OnNavigatedFrom でイベントハンドラを解除する場合、遷移先が同じ画面だと中断の場合なのでイベントハンドラを解除しないようにする必要があります;

知らないとなかなか見つけにくい不具合になるので注意ですね・・・