在Swift 2.0,单页面应用程序项目中,在XCode 7.0.1中,使用Swift依赖注入框架Swinject,我正在执行以下操作:
DuplicateProtocol.swift:
protocol DuplicateProtocol { var id: String { get } }
SingletonProtocol.swift:
protocol SingletonProtocol { var id: String { get } }
DuplicateProxy.swift
class DuplicateProxy: DuplicateProtocol {
let id: String
init ( id: String ) {
self.id = "DuplicateProxy." + id
}
}
SingletonProxy.swift:
class SingletonProxy: SingletonProtocol {
let id: String
init ( id: String ) {
self.id = "SingletonProxy." + id
}
}
ViewController.swift:
import UIKit
class ViewController: UIViewController
{
var duplicate: DuplicateProtocol?
var singleton: SingletonProtocol?
required init? ( coder aDecoder: NSCoder ) {
print( "ViewController.init?", duplicate, singleton )
super.init( coder: aDecoder )
}
override func viewDidLoad () {
print( "ViewController.viewDidLoad", duplicate, singleton )
super.viewDidLoad()
}
}
AppDelegate.swift:
import Swinject
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
var window: UIWindow?
func application ( application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]? ) -> Bool {
let container = Container()
let singleton = SingletonProxy( id: "first" )
container.register( SingletonProtocol.self ) { _ in singleton }
container.register( DuplicateProtocol.self ) { _ in DuplicateProxy( id: "second" ) }
container.registerForStoryboard( ViewController.self ) {
r, c in c.duplicate = r.resolve( DuplicateProtocol.self )
}
print( "AppDelegate.application" )
return true
}
}
这是我不幸得到的控制台日志:
ViewController.init? nil nil
AppDelegate.application
ViewController.viewDidLoad nil nil
尽可能简单地说:我需要做出哪些改变?谢谢你,JBM。
答案 0 :(得分:3)
如果要从故事板中实例化视图控制器,则无法使用初始化程序注入,因为UIKit框架会调用init?(coder:)
。
相反,应该使用属性注入来从故事板中实例化它:
class SomeViewController: UIViewController {
var duplicate: DuplicateProtocol?
var singleton: SingletonProtocol?
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
}
}
<强>更新强>
Swinject不支持UIWindow和初始视图控制器的隐式实例化。您需要显式实例化它们,如下例所示。
import Swinject
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var container: Container {
let container = Container()
let singleton = SingletonProxy( id: "first" )
container.register( SingletonProtocol.self ) { _ in singleton }
container.register( DuplicateProtocol.self ) { _ in DuplicateProxy( id: "second" ) }
container.registerForStoryboard( ViewController.self ) {
r, c in c.duplicate = r.resolve( DuplicateProtocol.self )
}
return container
}
func application ( application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]? ) -> Bool {
let window = UIWindow(frame: UIScreen.mainScreen().bounds)
window.makeKeyAndVisible()
self.window = window
let storyboard = SwinjectStoryboard.create(name: "Main", bundle: nil, container: container)
window.rootViewController = storyboard.instantiateInitialViewController()
return true
}
}
顺便说一下,你不必自己处理单例实例。 Swinject具有Singleton(aka Container)对象范围,可以使用.inObjectScope(.Container)
as documented here进行设置。
更新2
Swinject版本0.3支持UIWindow及其根视图控制器的隐式实例化,来自&#34; Main&#34;故事板。 Here is its documentation