我目前正在学习有关在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
类将在XCTestCase中使用,就像这样:
@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
答案 0 :(得分:0)
您可以将NSObject
上的Storyboard
用于不同的目的,其中之一也可以是委派。而不是像下面这样以编程方式设置它:
self.libraryTableView.dataSource = self
self.libraryTableView.delegate = self
您可以按住 control ,然后按如下所示设置相应的委托:
因为MovieLibraryDataService
符合UITableViewDataSource
和UITableViewDelegate
,而不是您的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 Controllers 往往会增长并变得像我们称之为Massive View Controller
答案 1 :(得分:0)
MovieLibraryDataService
只是另一个实现UITableViewDataSource
和UITableViewDelegate
的类,不同之处在于故事板将其实例化,并且storyboard-created
实例是通过{{1}绑定的} IBOutlet
。情节提要中的所有对象均为@IBOutlet var dataService: MovieLibraryDataService!
,这就是为什么如果对象未绑定到您已经使用的其他变量,则必须将它们绑定到要使用的变量。
为变量storyboard-created
命名只是一种幻想的说法,它应该被dataService
使用,在这种情况下,它是tableView的serve
,因为它实现了那些委托协议。
由于故事板实例化了dataSource and delegate
,因此您可以尝试将故事板中的dataService
绑定到dataService
。这是可能的,因为情节提要中有tableView
可引用。这将替换dataService
中的设置dataSource and delegate
。
viewController
也是情节提要中的AppDelegate
,因此情节提要中的NSObject
可以引用要使用的内容,从而避免了{@ 1}}的设置故事板。 (否则会很丑陋,也许只是macOS,因为Mac应用程序必须显示UIApplication/NSApplication
,即使它为空。)