###前提・実現したいこと
swiftでのstoryboardインスタンスの比較演算子===について思っていることと挙動が違うので教えて下さい。
該当のソースコードをデバッグすると、同じアドレスを参照してるのに
ifの結果はelseに飛んでしまいます。
どのようにしたら2つのstoryboardを比較できるのでしょうか?
一意で有効なプロパティがあればそちらでも比較してみたいです。
(実際にはないですが、storyboard.nameとかstoryboard.IDのようなものがあれば)
よろしくお願いいたします。
###発生している問題・エラーメッセージ
エラーメッセージはありません。
###該当のソースコード
swift
1ここにご自身が実行したソースコードを書いてください 2 3func receive(vc: UIViewController) { 4 var storyboard = UIStoryboard(name: "Name", bundle: nil) 5 if vc.storyboard === storyboard { 6 7 } else { 8 // vc.storyboardとstoryboardのアドレスは同じなのに処理はこちらにきてしまう 9 } 10}
↑2つのアドレスは同じなのに
###補足情報(言語/FW/ツール等のバージョンなど)
Xcode(7.3.1)
iOS_simulator(iphone6s)
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
いろいろ確認の仕方を誤って誤解しているような気がするので、コメントします。
まず、vc.storyboard
のツールチップ表示とstoryboard
のツールチップ表示の値が同じことから、この2つは同じだと判断しているようですが、vc.storyboard
のツールチップ表示は、vc.storyboard
の値を表示したものではなく、storyboard
というローカル変数の値を表示しているだけです。
LLDBコマンドで
po storyboard
po vc.storyboard
の両方を打って確認すれば、ツールチップに表示されているのはstoryboard
の方であることがわかると思います。まぁこれはXcodeの表示がわかりにくいと思うので、気持ちはわかりますが、大事な値を確認する時は、ツールチップ表示でなくpoコマンドで確認することをお勧めします。その方が記録も残りますし。
次に、
やはり、vc.storyboardとstoryboardは同じ実体を参照しているようです。
同じ実体だと思ってるのは画像の、0x000000010a7504b0 です。
とのことですが、0x000000010a7504b0は実体(インスタンス)ではありません。
(では、この値は何なのか?と聞かれたら、それはよくわかりません。eコマンドやpコマンドでオブジェクトを表示した時、デバッガーはそれをオブジェクトと認識せずに表示しますから、コンパイラー内部でオブジェクトを形成するための内部メモリ構造がそのまま出力されているのだと思います。その内部メモリ構造については仕様が公開されてないので正確なことはわかりません。オブジェクトを表示するならpoコマンドを使用して確認すべきだと思います。)
===演算子は、実体(インスタンス)が同じものか否かを比較する演算子ですから、
po storyboard
po vc.storyboard
の出力値が同じであれば、同じ実体(インスタンス)と判断されます。
少なくともあなたのコードは、
storyboard = UIStoryboard(name: "Main", bundle: nil)
で、新しい実体(インスタンス)を作っていますから、
それと既存のvc.storyboardの実体(インスタンス)が===で同じと判断されることは絶対にありません。
「比べたいのは、参照先の実在のストーリーボードです。」と書いている意味は、おそらく実体(インスタンス)が同じか否かを比較したいのではなく、同じストーリーボードファイルを使用して生成したものか否かを比較したいのだと思います。
既に調べられているように、どのストーリーボードファイルで使用して生成したものかを示すプロパティはないようです。今回の場合、結局は通常モードで動作しているかメンテナンスモードで動作しているかを確認したいだけのような気がするので、vcのstoryboardを生成する時に、どちらのstoryboardを生成したか(というか現在どちらのモードで動作しているか)をAppDelegateのプロパティとかに覚えておけばよいだけのように思います。
投稿2016/07/19 09:20
総合スコア6299
0
検証は全く行っていませんので、ただのアイデアだと思って下さい。
isEqual
swift
1if (vc.storyboard.isEqual(storyboard)) { 2 print("equal") 3}
.hash
一意で有効なプロパティになるのかどうか分かりませんが。
swift
1if (vc.storyboard.hash == storyboard.hash) { 2 print("equal") 3}
投稿2016/07/19 02:15
総合スコア16731
0
該当のソースコードをデバッグすると、同じアドレスを参照してるのに
ifの結果はelseに飛んでしまいます。
こちらはアドレスは違うと思います、デバックでそれぞれのアドレスを確認してみてください。
e vc.storyboard
とe storyboard
で両方出力してみると分かると思います。
こちらのメソッドは渡されたViewController
とStoryboard
を比較していますが、Storyboardが自分自身のいるStoryboardとして比較しているのでしたら、この場合はStoryboardのインスタンスを新たに作っているので同じではないです。
ロジック自体はインスタンスを渡せばちゃんと判定できています、このメソッドを使用したい状態とはどのような時でしょうか?
アドレスが同じと確認したコード
swift
1import UIKit 2 3class ViewController1: UIViewController { 4 5 override func viewDidLoad() { 6 super.viewDidLoad() 7 } 8 9 @IBAction func pushNextButton(sender: UIButton) { 10 11 let nextStoryboard = UIStoryboard(name: "Main2", bundle: nil) 12 let vc2 = nextStoryboard.instantiateInitialViewController() as! ViewController2 13 vc2.myStoryboard = nextStoryboard 14 self.navigationController?.pushViewController(vc2, animated: true) 15 } 16} 17 18 19class ViewController2: UIViewController { 20 21 var myStoryboard: UIStoryboard! 22 23 override func viewDidLoad() { 24 super.viewDidLoad() 25 26 receive(self) 27 } 28 29 func receive(vc: UIViewController) { 30 31 if vc.storyboard === myStoryboard { 32 print("同じ") 33 //=> 同じ 34 } else { 35 print("違う") 36 } 37 } 38}
投稿2016/07/17 08:06
編集2016/07/17 12:17総合スコア8490
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/17 11:01
2016/07/17 12:24
2016/07/17 21:08 編集
2016/07/17 23:13
2016/07/18 01:48
2016/07/18 01:57
2016/07/18 02:28
2016/07/18 03:40
2016/07/19 01:34
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/19 16:11