7

Swinjectプロジェクトの resolve メソッドに引数を渡そうとするテスト プロジェクトがあります。

これは、私の Swinject ストーリーボード拡張ファイルに含まれているものの例です。

import Swinject

extension SwinjectStoryboard {

    class func setup() {

        let mainDm = MainDM()

        defaultContainer.register(MainDM.self) { _ in
            mainDm
        }

        defaultContainer.registerForStoryboard(ViewController.self) { r, c in
            c.dm = r.resolve(MainDM.self)
            c.container = defaultContainer

        }


        defaultContainer.register(GetMessageAction.self) { _, delegate in
            GetMessageAction(dm:mainDm, delegate: delegate)
        }

    }

}

私のViewControllerでは、GetMessageActionを解決するために次のことをしようとしています

@IBOutlet weak var myText: UILabel!

    var dm:MainDM!
    var container:Container!

    override func viewDidLoad() {
        super.viewDidLoad()

        NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(3), target: self, selector: #selector(ViewController.getMessage), userInfo: nil, repeats: false)

    }

    func getMessage() {

        let action:GetMessageAction? = container.resolve(GetMessageAction.self, argument: self)!
        action?.execute()

    }

getMessage 関数を実行すると、次のメッセージが表示されます

致命的なエラー: オプション値のラップ解除中に予期せず nil が見つかりました

4

3 に答える 3

3

引数による解決は、引数の型が正確に一致することに依存するため、渡されたオブジェクトをダウンキャストする必要があります。

container.resolve(GetMessageAction.self, argument: self as GetMessageActionDelegate)!

GetMessageActionDelegateそれがコンストラクターで渡されるデリゲートのタイプであると仮定しGetMessageAction(dm:delegate:)ます。

于 2016-06-13T16:30:28.773 に答える
1

Storyboard で作成した ViewController の Swift ファイルはinit(NSCoder) を宣言する必要があります。実際には README.md には記載されていません。これに関する問題を開くことを考えています...

   required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

まさにこの手法を使用して、私のオープン ソース プロジェクトを見ることができます。ここでは、LoadingDataVC などのSwinjectStoryboardの拡張機能を使用して依存関係を設定しています。

extension SwinjectStoryboard {
    class func setup() {

        defaultContainer.register(HTTPClientProtocol.self) { _ in
            HTTPClient()
        }.inObjectScope(.Container)

        defaultContainer.register(APIClientProtocol.self) { r in
            APIClient(
                httpClient: r.resolve(HTTPClientProtocol.self)!
            )
        }.inObjectScope(.Container)

        defaultContainer.register(ImagePrefetcherProtocol.self) { _ in
            ImagePrefetcher()
        }.inObjectScope(.Container)

        defaultContainer.registerForStoryboard(GameVC.self) { r, c in
            c.imagePrefetcher = r.resolve(ImagePrefetcherProtocol.self)
        }

        defaultContainer.registerForStoryboard(LoadingDataVC.self) { r, c in
            c.apiClient = r.resolve(APIClientProtocol.self)
            c.imagePrefetcher = r.resolve(ImagePrefetcherProtocol.self)
        }
    }
}

必要な init を取得したら、動作するはずです。:)

于 2016-07-14T09:44:04.233 に答える
0

によって登録されたビュー コントローラを取得するには、ストーリーボードの次のいずれかのメソッドを使用しますregisterForStoryboard

  • instantiateViewControllerWithIdentifier
  • instantiateInitialViewController

https://github.com/Swinject/Swinject/blob/v1/Documentation/Storyboard.md https://github.com/Swinject/SwinjectStoryboard/issues/5

于 2016-06-12T03:07:58.513 に答える