質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

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

Swift

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

Q&A

解決済

3回答

6933閲覧

nilが入っていないはずなのにエラー

Blue0999

総合スコア148

Xcode

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

Swift

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

0グッド

0クリップ

投稿2016/04/03 07:10

編集2016/04/03 07:52

プレイグランドで下記のコードを実行できるのにXcodeではエラーになっていまいます!
下記のコードではnilが入っていた変数aをメソッドにより中身をクラスAに入れ替えた上でクラスAのプロパティを使用しています。もちろんエラーにはなりません。
class A {
var num = 0
}

class B {
var a: A?
func assignment() {
a = A()
}
}

var b = B()
b.assignment()
print(b.a!.num) // 0と出力

しかしこれと同じような事をXcodeで試すとエラーになります。


状況
クラスViewController2の他に別のファイルにクラスViewController(既存の)が宣言されていてその中にmainStoryboardと接続されたラベル(myLabel)が1つある。

nilが入っていた変数viewControllerをviewDidLoadメソッド内でViewController()を代入した上でクラスViewControllerのプロパティmyLabelを参照しますが、nilが入っている変数をアンラップしてしまったとエラーが表示されます。クラスViewControllerに変更したのでnilは入っていないはずなのですが…可能性のある原因がわかる方教えてください!

class ViewController2: UIViewController {

var str = "Hello" var viewController: ViewController? = nil override func viewDidLoad() { super.viewDidLoad() viewController = ViewController() str = viewController!.myLabel.text } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }

}


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

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

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

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

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

guest

回答3

0

なぜ質問の様なことをしたいのか意図が理解できませんが。

viewController = ViewController()
の書き方ではStoryboardからViewControllerを読み込んで生成はされません。

nilが入っていないはずなのにエラー

swift

1// Implicitly Unwrapped Optional型なので、宣言はされていても初期値はnilです 2// Storyboardが読み込まれた時点で生成されます。 3@IBOutlet weak var myLabel: UILabel!

以下の様に書くことでとりあえずはやりたい事はできると思います。

swift

1override func viewDidLoad() { 2 super.viewDidLoad() 3 4 // StoryboardのViewControllerのStoryboard IDに"ViewController"を設定してあるという前提 5 viewController = storyboard?.instantiateViewControllerWithIdentifier("ViewController") as? ViewController 6 print(viewController!.view) 7 str = viewController!.myLabel.text! 8}

・StoryboardからViewCotntrollerを生成する
・この状態ではViewControllerが生成されただけなのでIBOutlet等のパーツはnilです。

print(viewController!.view)
の行は意味が無いように思いますが、生成したviewControllerのviewにアクセスすることで
IBOutletなどのパーツが生成されます。(ViewControllerのviewDidLoadが呼ばれます。)
※この行が無いとmyLabelがnilで落ちます。

以上です、しかし取得できるラベルのテキストはStroryboardのラベルに初期設定した文字列なのでいつも同じ文字列です。

投稿2016/04/03 09:22

編集2016/04/03 12:08
_Kentarou

総合スコア8490

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

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

Blue0999

2016/04/04 09:28

ご回答ありがとうございます。printでviewControllerのviewにアクセスする事でviewDidloadを呼び出すという方法もあるんですね…勉強になりました。
guest

0

ベストアンサー

viewController = ViewController()
は、新しいViewControllerを生成しますが、Storyboardで接続したmyLabelをロードすることまではしてくれません。(Storyboardで定義された画面の中で、どの画面をロードすればいいか指定してもらわないとわからないからです。)
このため、myLabelがnilとなり、アンラップエラーになったのだと思います。

新しいViewControllerを生成して、Storyboardで接続した部品をロードするには、ViewController2がStoryboardで読み込まれたものであれば
viewController = self.storyboard?.instantiateViewControllerWithIdentifier("指定画面のStoryboardID")
とすればよいです。

ただ、ちょっと気になるのは、通常プロジェクトを作成するとViewControllerというのがデフォルトで作られ、それが最初にロードされるビューコントローラーになると思います。
もしViewController2が、もともとViewControllerから呼び出されたもので、呼び出し元(ViewController)のmyLabelを参照したいということであれば、新しいViewControllerを生成するのではなく、呼び出し元のViewControllerを取得する必要があります。
その方法は、コンテナ埋め込みしているならparentViewControllerを参照すればいいし、モーダル画面遷移しているならpresentingViewControllerを参照すればいいです。また、画面遷移方法によらない汎用的な方法としてdelegateを組み込む方法もあります。

投稿2016/04/03 08:46

編集2016/04/03 09:25
TakeOne

総合スコア6299

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

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

Blue0999

2016/04/04 09:36 編集

ご回答ありがとうございます! 詳しく説明していただきとても助かりました。viewDidloadが実行する前にStoryboardで接続した部品にアクセスする事は出来ないんですね…
guest

0

viewControllerの中のmyLabelがnilなのでは?

投稿2016/04/03 07:42

Stripe

総合スコア2183

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

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

Blue0999

2016/04/03 07:50

ご回答ありがとうございます! 確認してみたのですがmyLabelにはちゃんと中身があるようでこのように宣言されています @IBOutlet weak var myLabel: UILabel!
AOKINAO

2016/04/03 08:31

viewDidLoadで宣言されているviewControllerとインスタンスと、別のところで宣言されているviewControllerのインスタンスは、別物ではありませんか?
Blue0999

2016/04/03 09:35

別のところに宣言されているviewControllerをコメントアウトで消すとviewDidLoadで宣言されているviewControllerにエラーが出たのでたぶん同じものだと思うのですが…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問