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)
    }

您可以使用这种技术查看我的开源项目,我在这里使用 SwinjectStoryboard 的扩展设置依赖项,例如LoadingDataVC

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)
        }
    }
}

一旦你有所需的初始化它应该工作!:)

于 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 回答