0

我正在按照 SOLID 原则和 MVC 架构构建一个简单的应用程序。我想在我的 NetworkClass 中解析来自服务器的图像,并在我的 ViewController 中的 CollectionView 中显示它们。这是我的视图控制器:

protocol NetworkServiceProtocol {
    func parseImages() -> [Image]
}

class ViewController: UIViewController {
    
    @IBOutlet weak var imageCollection: UICollectionView!

    private let networkService: NetworkServiceProtocol
   
    convenience init(service: NetworkServiceProtocol) {
        self.init()
        self.networkService = service
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        images = networkService!.parseImages()
    }

}

这是我的 NetworkService 类(稍后我将进行解析):

class NetworkService: NetworkServiceProtocol {
    
    func parseImages() -> [Image] {
        return [Image]()
    }
    
}

问题是,当我运行此代码时,它在viewDidLoad()调用networkService!. 我看到问题在于实例化 NetworkServiceProtocol。我应该在哪里以及如何实例化它?任何帮助表示赞赏!

4

2 回答 2

0

发生这种情况是因为您正在从情节提要初始化您ViewController的情节提要,而情节提要正在使用您的required init?(coder: NSCoder)which throws fatalError

为了解决它,首先更改:

    required init?(coder: NSCoder) {
            //error: networkService not initialized
            super.init(coder: coder)
        }

现在这个错误是因为networkService没有通过这个初始化器初始化的类属性。现在为了解决这个问题,你可以在类中给它一个默认属性,然后在let networkService = NetworkServiceProtocol()通过情节提要初始化之后将它设置为你想要的NetworkServiceProtocol对象。(另一种选择是使其成为可选)

注意:您必须删除私有访问修饰符才能从另一个类中设置它。如果您仍然希望它是私有的,那么您必须为其编写一个 setter 方法。

于 2021-09-11T11:54:34.437 回答
0

我通过取消选中我的 View Controller 作为 Storyboard 中的 Initial View Controller 并将以下代码添加到我的 AppDelegate 中解决了这个问题:

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        let storybaord = UIStoryboard(name: "Main", bundle: Bundle.main)
        let initialVC = storybaord.instantiateViewController(withIdentifier: "ViewController") as! ViewController
        initialVC.networkService = NetworkService()
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = initialVC
        self.window?.makeKeyAndVisible()
        
        return true
    }
于 2021-09-11T12:21:38.517 回答