为什么在Swift中初始化类时不需要所有对象?

时间:2017-02-24 02:30:59

标签: ios swift oop

我正在编写一本用Swift编写的TDD书来学习如何使用该语言。我注意到在代码库中,某些对象并不需要分配内存才能使用。例如,我们创建了一个隐式展开的可选命名sut,其中我理解为该对象分配内存但实际上并没有创建它。但是在名为setup的方法中,我们创建并使用了UIStoryboard对象。我很困惑为什么这是可能的以及为什么它不需要为UIStoryboard对象分配内存。这是代码:

import XCTest
@testable import ToDo

class ItemListViewControllerTests: XCTestCase {

    var sut: ItemListViewController!

    override func setUp() {
        super.setUp()

        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)

        sut = storyboard.instantiateViewController(withIdentifier: "ItemListViewController") as! ItemListViewController

        _ = sut.view
    }

    override func tearDown() {

        super.tearDown()
    }

    func test_TableViewIsNotNil_AfterViewDidLoad() {

        XCTAssertNotNil(sut.tableView)
    }

    func test_loadingView_LoadsTableViewAndSetsTableViewDataSource(){

        XCTAssertTrue(sut.tableView.dataSource is ItemListDataProvider)

    }
}

2 个答案:

答案 0 :(得分:3)

var sut: ItemListViewController!

声明一个名为sut的属性,它是对ItemListViewController的引用。它没有分配任何内存。

sut是一个隐式解包的可选项,因此只是一个普通的可选项,它可以是nil,Swift不会抱怨它在初始化阶段没有初始化。

由于属性将在对象生命周期的早期初始化(在测试的setup函数中),并且它没有有条件地初始化,所以"知道&#34 ;它会有价值。

将其声明为隐式展开的可选项意味着您不必在每次使用时都展开展开变量;你可以使用它,但就像任何其他力量解包一样,如果 为零,你将会崩溃。

现在,这个:

let storyboard = UIStoryboard.init(name: "Main", bundle: nil)

初始化UIStoryboard的实例并将其链接到捆绑包中的主故事板,并且:

sut = storyboard.instantiateViewController(withIdentifier: "ItemListViewController") as! ItemListViewController

实际执行ItemListViewController实例的分配,方法是使用标识为ItemListViewController

的场景要求storyboard对象执行此操作

答案 1 :(得分:1)

您已经在声明let storyboard时已经这样做了,这意味着创建故事板常量实例,您声明var sut意味着您创建变量实例,但在函数范围之外将允许您使用它关于同一测试类的其他功能,

你不需要在其他地方使用故事板实例,所以你把它放在设置中,因为它每次运行测试时都会运行以创建新的sut,新的sut将确保它是独立的,没有任何东西改变了它的财产