🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

697閲覧

ViewControllerをグローバルで定義したい

msa_winnie

総合スコア17

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2019/09/11 05:07

質問

現在、ビューワーアプリを製作中です。
メインのViewControllerクラスで定義した変数を色々なクラスで参照したいため、ViewControllerをグローバルで定義したいと思っています。
グローバルで定義しても問題ありませんでしょうか。
サンプルアプリを見ていると大抵AppDelegateクラス内で定義されています。
グローバルで定義して試してみたところ動作的には問題なさそうですが、今後致命的な問題が出ないか心配です。
また、その他に良い方法がありましたら教えていただきたいです。

初歩的な質問で申し訳ありませんが、ご教示のほどお願い申し上げます。

該当のソースコード

swift5

1 2///********グローバルで定義 3var g_Vc : ViewController! // 共用ビューコントローラー 4 5 6///******** ViewController 7class ViewController: UIViewController{ 8 9 var appDelegate:AppDelegate = UIApplication.shared.delegate as! AppDelegate 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 } 14} 15 16 17///******** AppDelegate 18@UIApplicationMain 19class AppDelegate: UIResponder, UIApplicationDelegate{ 20 21 var window: UIWindow? 22 var NaviController: NavigationController? 23 24 // アプリを起動する際に呼び出されるメソッド 25 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 26 27 // ウィンドウの設定 28 g_Vc = ViewController() 29 NaviController = NavigationController(rootViewController: g_App.m_Vc) 30 self.window = UIWindow(frame: UIScreen.main.bounds) 31 self.window?.rootViewController = NaviController 32 self.window?.backgroundColor = UIColor.white 33 self.window?.makeKeyAndVisible() 34 35 return true 36 } 37} 38

補足情報

Xcode:Version 10.2
Swift5
iOS12.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t_obara

2019/09/11 05:11

AppDelegateの派生クラスを利用すれば良いのでは?
msa_winnie

2019/09/11 05:30

t_obara様 教えていただきありがとうございます。 >AppDelegateの派生クラスを利用すれば良いのでは? すみません。 派生クラスを具体的にどのように利用すれば良いのか教えていただけますでしょうか。 申し訳ありませんがよろしくお願いいたします。
t_obara

2019/09/11 06:14

すでに提示されたコードでも利用されている様に、AppDelegateをViewから参照している様に、どこからでも参照できるクラスがあるのであれば、グローバルのViewControllerの代わりに、そちらに必要な情報を設定すれば良いという意図です。
msa_winnie

2019/09/11 07:25 編集

t_obara様 教えていただきありがとうございます。 どこからでも利用できるクラスを用意すれば良いのですね。 例えば、ViewControllerを直接グローバルにではなく、以下のようにどこからでも参照できるクラス内にViewControllerを定義するということであっていますでしょうか。 ************************************** var g_App = App() class App{ var m_Vc : ViewController! // 共用ビューコントローラー } class AppDelegate: UIResponder, UIApplicationDelegate{ 〜〜 // アプリを起動する際に呼び出されるメソッド func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { g_App. m_Vc = ViewController() 〜〜 } } **************************************
t_obara

2019/09/11 07:45

まず、ViewControllerはViewの振る舞いを制御するものなので、共有しない方が良いです。振る舞いに影響を与える変数などを共有すべきです。 また、g_Appって結局グローバル変数と同義です。g_Appなんて定義しなくてもすでにAppDelegateが参照できるので、それ経由でアクセスすれば良いという提案です。AppDelegateのメンバ変数や、別に定義したクラスインスタンスを持たせれば良いです。
msa_winnie

2019/09/11 07:58

t_obara様 丁寧に教えていただきありがとうございます。 理解不足で申し訳ありません。 以下のようにAppDelegate内に参照したい変数を定義して、 他の色々なクラスで参照したいときは、UIApplicationからdelegateを取得してアクセスするということであっていますでしょうか。 ************************************** class AppDelegate: UIResponder, UIApplicationDelegate{ 〜〜 var m_sansyo : Int = 0 // 参照したい変数 〜〜 } ************************************** class 色々なクラス{ 〜〜 var appDelegate:AppDelegate = UIApplication.shared.delegate as! AppDelegate // 参照したい変数を取得 func getsansyo() -> Int { return appDelegate. m_sansyo } 〜〜 }
t_obara

2019/09/11 08:05

やってみましょう。デバッガで参照するとよくわかるかと思います。
msa_winnie

2019/09/11 08:27

t_obara様 やってみました。上記の方法で無事に参照することができました。 AppDelegateを利用することで、グローバル変数にしなくても済むのですね。 AppDelegateについてはよくわからない部分が多かったのでこれから勉強します。 ありがとうございました。
guest

回答1

0

ベストアンサー

グローバルで定義しても問題ありませんでしょうか。

動作上問題が無いかという意味であれば、動作チェックして問題がなければ大丈夫でしょうね。
一般的にはグローバル変数はメンテナンスの観点からなるべく減らすべきと考えられています。

また、その他に良い方法がありましたら教えていただきたいです。

そのためには、ViewControllerの何の変数をどこのクラスで使いたいのか、そもそも別のクラスでその変数を参照する必要があるのか、といったもろもろを含めて判断しないといけませんので、今の情報だけで○○がオススメという事は言えません。
(かと言って全部情報を出されても私は回答できかねますが)

投稿2019/09/11 06:06

編集2019/09/11 06:08
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msa_winnie

2019/09/11 07:35

takabosoft様 教えていただきありがとうございます。 >一般的にはグローバル変数はメンテナンスの観点からなるべく減らすべきと考えられています。 そうですよね。安易にグローバル変数にするのは避けたいです。 >今の情報だけで○○がオススメという事は言えません。 メインのViewControllerの子供のViewControllerで変数を参照したりしています。 たしかに参照しなくても済む可能性があるので、再度コードを見直してみます。
hameji

2019/09/12 02:56 編集

通常は、データは別に持っていて、 各viewの表示・利用の際に読み出すのが一般的だと思います。 AViewに let animalName: String = "ライオン" let animalImage: UIImage = UIImage(named: "lion.png") などある場合に、 他のview(BView)でわざわざ let name: String = AView.animalName let image: UIIMage = AView.animalImage などとはせず、 取得時or初回起動時(AViewなどで)userdefaults(他のデータ永続化方法でも可)などに保存すれば、 BViewでuserdefaults.string(forKey: "animalName")で読み出せます。 CViewでも同様で、管理しやすいと思います。 viewcontroller自体をグローバルにするのは、 不要なもの(viewのlifecycleなど)まで保持されてしまうことが懸念されます。 どの永続化方法がいいのかは、時と場合によります。 簡便的にはuserdefaultsですが、なんでもかんでも保存すれば良いという訳でもなく、議論を呼ぶところではありますが、、、
msa_winnie

2019/09/13 04:03

hameji様 教えていただきありがとうございます。 userdefaultsなどを利用する方法も参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問