LoginSignup
2
4

More than 3 years have passed since last update.

【Swift、Objective-c】画面遷移とメモリ使用について

Posted at

Swift、Objective-cでの画面遷移をする際の遷移方法、メモリ使用についてまとめました。

画面遷移する方法

ViewController間での画面遷移は、storyboard ID、Segue Identifierを使用する方法と
dismissViewControllerAnimatedを使用する方法があります。

Objective-c

//storyboard IDを使用した画面遷移
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"storyboard ID"];
[self presentViewController:vc animated:NO completion:nil];

//Segue Identifierを使用した画面遷移
[self performSegueWithIdentifier:@"Segue Identifier" sender:self];

//dismissViewControllerAnimatedを使用した画面遷移
[self dismissViewControllerAnimated:NO completion:nil];
Swift

//storyboard IDを使用した画面遷移
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "storyboard ID") as! nextViewController
        self.present(secondViewController, animated: true, completion: nil)

//Segue Identifierを使用した画面遷移
self.performSegue(withIdentifier: "Segue Identifier", sender: self)

//dismissViewControllerAnimatedを使用した画面遷移
self.dismiss(animated: false, completion: nil)

画面遷移する場合のメモリ使用量

2つのViewController間を画面遷移した場合、メモリ使用量の変化は以下のようになります。

  • dismissViewControllerAnimatedで画面遷移をした場合のメモリ使用量
    画面遷移した時に、メモリが解放されます。
    dismiss画面遷移.jpg

  • storyboard ID、Segue Identifierで画面遷移をした場合のメモリ使用量
    画面遷移をした時に新しく画面を作成していくため、画面遷移してもメモリが解放されず、
    メモリが溜まっていきます。
    present画面遷移.jpg

dismissViewControllerAnimated以外での画面遷移では新しく画面を作成する。
そのため、storyboard ID、Segue Identifierのみで画面遷移を続けた場合、メモリが解放されず溜まっていき、
結果として動作が重くなりアプリが強制終了してしまう。
そのため、新しい画面への画面遷移以外は、dismissViewControllerAnimatedで戻った方が良い。

dismissViewControllerAnimatedで遷移した場合の問題点

メモリ解放のため、dismissViewControllerAnimatedを使用した画面遷移を使用していきたいが、dismissViewControllerAnimatedは、現在表示されているViewControllerを削除することで画面遷移するため、戻った後のViewControllerは更新されない。

そのため、TableViewの画面情報を再表示したい場合、追加の処理を行う必要がある。

NSNotificationを使用したTableViewの更新

解決策として事前にmainViewControllerでNSNotificationの通知要求を登録しておき、遷移後のViewControllerから画面遷移する時に、通知を送ることで画面遷移後にTableViewを更新することができます。

Objective-c mainViewController
- (void)viewDidLoad {
     [super viewDidLoad];

     //通知要求の登録をする
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hoge:) name:@"reload" object:nil];
}

//通知を受信した時に実行する
-(void)hoge:(NSNotification *)notification {
     if([[notification name]isEqual:@"reload"]) {
          //TableViewの更新処理
          [tableView reloadData];
     }
}
Objective-c nextViewController

//画面遷移後に通知を送信する
[self dismissViewControllerAnimated:NO completion:^{
     [[NSNotificationCenter defaultCenter]postNotificationName:@"reload" object:self];
}];
Swift mainViewController

override func viewDidLoad() {
     super.viewDidLoad()

     //通知要求の登録をする
     let nc = NotificationCenter.default
     nc.addObserver(self, selector: #selector(hoge), name: Notification.Name(rawValue:"reload"), object: nil)
}

//通知を受信した時に実行する
@objc func hoge(notification: Notification?) {
     if notification!.name.rawValue == "reload" {
          tableView.reloadData()
     }
}
Swift nextViewController
//画面遷移後に通知を送信する
self.dismiss(animated: false, completion: {
     NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reload"), object: nil)
})

mainViewControllerまで一気に戻る場合

複数画面遷移している状態から一気にmainViewControllerまで戻る場合以下のようにすれば良い。

Objective-c

[[UIApplication sharedApplication].windows[0].rootViewController dismissViewControllerAnimated:NO completion:nil];
Swift

let window = UIApplication.shared.windows[0].rootViewController
window?.dismiss(animated: false, completion: nil)

参考

presentViewController:animated:completion:
dismissViewControllerAnimated:completion:
https://tutorialmore.com/questions-2605800.htm

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4