17700


swift＆オブジェクト指向触りたての初心者です．  
凄く初歩的な質問だと思いますが，お答えいただけると幸いです．

現在，ViewControllerクラスにあるメソッドを別の（Testという名前の）クラスから呼びだそうとしています．その際，unexpectedly
found nil while unwapping an Optional
valueというエラーがでて停止してしまいます．原因が分からず困っています・・・．

色々回っている際，`var viewController:ViewController!` の部分を `var
viewController＝ViewController()` と書いているところもあり，どちらが正しいのかもわからない状態です．

よろしくお願いいたします．

ViewController.swift

[code]

    import UIKit //impot KIt..
    
    class ViewController: UIViewController,UIGestureRecognizerDelegate{
    
        private var myImageView:UIImageView!
        var myLabel: UILabel!
        let Ex = Test()
    
        @IBOutlet weak var status: UILabel!
    
        override func viewDidLoad() { //make function.
    
            super.viewDidLoad()
            //background image
            self.view.backgroundColor = UIColor(patternImage: UIImage(named: "cotton-a.png")!)
            Ex.ex()
    
        }
    
    
    
        override func didReceiveMemoryWarning() {
    
            super.didReceiveMemoryWarning()
    
        }
    
        func test(){
            myImageView = UIImageView(frame: CGRectMake(0, 0, 600, 100))
    
            var image : UIImage?
    
            image = UIImage(named: "check.png")
            myImageView.image = image
            myImageView.layer.position = CGPoint(x:self.view.bounds.width/2,y:self.view.bounds.height/2)
    
            self.view.addSubview(myImageView)
    
        }
    }
    
[/code]

Test.swift

[code]

    import Foundation
    
    class Test: NSObject {
        var viewController:ViewController!
    
        func ex(){
    
            for var i=0 ; i<10 ; i++ {
    
                println("i is \(i)")
    
                if(i==9){
                    //次でエラーが出て落ちる．
                    viewController.test()
                }
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2015-10-15T08:55:50.117
17679
2015-10-21T06:54:41.180
2015-10-15T09:58:05.203
7362
12793
question
ios swift
unexpectedly found nil while unwapping an Optional value エラーが出る

[code]

    // Test.swift
    
    var viewController:ViewController!
    
[/code]

宣言時、記号`!`がついた変数は、 _Implicitly unwrapped optional_ といいますが、 _Optional_
型であることに変わりはなく、値が`nil`である可能性があります。プログラマの責任において、なにか値を代入して、`nil`にならないようにすることを求められます。
_Implicitly unwrapped optional_
を使う場合は、できるだけ早期に、代入をしましょう。現状のプログラムでは、なにも代入していないので、「Optionalの値にnilが見つかったよ」というエラーダイアログが出ます。  
`UIViewController`のサブクラスでは、`viewDidLoad`メソッドで、インスタンスの初期化をすることが多いですが、クラス一般でいうなら、イニシアライザで初期化するのが望ましい処理です。
_Implicitly unwrapped optional_ のインスタンス変数（プロパティ）への代入も、イニシアライザで行いましょう。

[code]

    class Test: NSObject {
    
        weak var viewController:ViewController! // 循環参照を予防する意味で、weak属性をしています。
    
        init(viewController: ViewController) {
            self.viewController = viewController
        }
        ........
    }
    
[/code]

イニシアライザに引数を持たせることで、例外なく`viewController`に代入が行われるように配慮しています。

以下は、ご提示のコード全体の修正案です。

[code]

    import UIKit
    
    class ViewController: UIViewController,UIGestureRecognizerDelegate{
    
        // 生成しないかもしれないインスタンスは、Optionalにしておきましょう。
        private var myImageView:UIImageView?
        var myLabel: UILabel?
        var ex: Test! // viewDidLoad内で初期化する。
    
        @IBOutlet weak var status: UILabel!
    
        override func viewDidLoad() {
    
            super.viewDidLoad()
    
            ex = Test(viewController: self) // exの初期化。
            ex.ex()
    
        }
    
    
    
        override func didReceiveMemoryWarning() {
    
            super.didReceiveMemoryWarning()
    
        }
    
        func test(){
            myImageView = UIImageView(frame: CGRectMake(0, 0, 600, 100))
            if let view = myImageView { // Optional Binding
                var image : UIImage?
    
                image = UIImage(named: "check.png")
                view.image = image
                view.layer.position = CGPoint(x:self.view.bounds.width/2,y:self.view.bounds.height/2)
    
                self.view.addSubview(view)
            }
        }
    }
    
    // 小規模なクラスなら、いちいち別ファイルに起こす必要はありません。
    class Test: NSObject {
    
        weak var viewController:ViewController!
    
        init(viewController: ViewController) {
            self.viewController = viewController // viewControllerに代入
        }
    
        func ex(){
    
            for var i=0 ; i<10 ; i++ {
    
                print("i is \(i)")
    
                if(i==9){
                    viewController.test()
                }
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2015-10-15T22:50:42.343
17700
2015-10-21T06:54:41.180
2015-10-21T06:54:41.180
7362
7362
17679
answer