繁体   English   中英

StoryBoard / Interface Builder中NSObject的功能是什么?

[英]what is the function of NSObject in StoryBoard / Interface Builder?

我目前正在观看有关在Swift中进行iOS测试驱动开发的视频教程课程,但是在View Controller中测试Table View时,我陷入了困境,因为我不明白为什么在Interface builder中我们需要NSObject如下图所示:

电影库数据服务继承了NSObject类:

在此处输入图片说明

MovieLibraryDataService的类如下:

import UIKit

class MovieLibraryDataService: NSObject, UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell()
    }


}

MovieLibraryDataService将使用MovieLibraryDataService类,如下所示:

@testable import FilmFest
class LibraryViewControllerTests: XCTestCase {

    var sut: LibraryViewController!

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
        sut = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LibraryViewControllerID") as! LibraryViewController
        _ = sut.view
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    // MARK: Nil Checks
    func testLibraryVC_TableViewShouldNotBeNil() {
        XCTAssertNotNil(sut.libraryTableView)
    }

    // MARK: Data Source
    func testDataSource_ViewDidLoad_SetsTableViewDataSource() {
        XCTAssertNotNil(sut.libraryTableView.dataSource)
        XCTAssertTrue(sut.libraryTableView.dataSource is MovieLibraryDataService)
    }

    // MARK: Delegate
    func testDelegate_ViewDidLoad_SetsTableViewDelegate() {
        XCTAssertNotNil(sut.libraryTableView.delegate)
        XCTAssertTrue(sut.libraryTableView.delegate is MovieLibraryDataService)
    }

    // MARK: Data Service Assumptions
    func testDataService_ViewDidLoad_SingleDataServiceObject() {
        XCTAssertEqual(sut.libraryTableView.dataSource as! MovieLibraryDataService, sut.libraryTableView.delegate as! MovieLibraryDataService)
    }



}

以及LibraryViewController的定义:

import UIKit

class LibraryViewController: UIViewController {

    @IBOutlet weak var libraryTableView: UITableView!
    @IBOutlet var dataService: MovieLibraryDataService!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.libraryTableView.dataSource = dataService
        self.libraryTableView.delegate = dataService
    }


}

我真的不明白为什么我需要制作那个MovieLibraryDataService

我通常使用:

self.libraryTableView.dataSource = self
self.libraryTableView.delegate = self

但是为什么我需要写:

self.libraryTableView.dataSource = dataService
self.libraryTableView.delegate = dataService

编辑

您可以将Storyboard上的NSObject用于不同的目的,其中之一也可以是委托。 而不是像下面这样以编程方式设置它:

self.libraryTableView.dataSource = self
self.libraryTableView.delegate = self

您可以保持控制 ,然后按如下所示设置相应的代表:

在此处输入图片说明

原始答案

因为MovieLibraryDataService符合UITableViewDataSourceUITableViewDelegate而不是您的LibraryViewController

如果要像往常一样更改它,请将代码更改为:

class LibraryViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var libraryTableView: UITableView!
    var dataService = MovieLibraryDataService()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.libraryTableView.dataSource = self
        self.libraryTableView.delegate = self
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell()
    }
}

我个人建议保持现有状态,因为View Controller会不断增长并变得像我们称之为Massive View Controller

MovieLibraryDataService只是另一个实现UITableViewDataSourceUITableViewDelegate类,区别在于情节@IBOutlet var dataService: MovieLibraryDataService!实例化它,并且由IBOutlet @IBOutlet var dataService: MovieLibraryDataService!绑定了@IBOutlet var dataService: MovieLibraryDataService! storyboard-created实例@IBOutlet var dataService: MovieLibraryDataService! 情节提要中的所有对象都是storyboard-created ,这就是为什么如果对象未绑定到您已经使用的其他变量,则必须将它们绑定到要使用的变量。

给变量dataService命名只是一种幻想的说法,因为它实现了那些委托协议,因此在本例中它应该serve tableView的dataSource and delegate

由于dataService是由情节dataService实例化的,因此可以尝试是否将情节dataService绑定到tableView 这是可能的,因为在情节dataService中有dataService引用。 这将替换viewController中的设置dataSource and delegate

另一个例子

AppDelegate也是情节提要板中的NSObject ,因此情节提要板中的UIApplication/NSApplication能够引用要使用的内容,从而避免了必须在情节提要板外部设置AppDelegate自己。 (否则会很丑,也许只是macOS,因为Mac应用程序必须显示一个Menu即使它是空的。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM