[英]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
符合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 Controller会不断增长并变得像我们称之为Massive View Controller
MovieLibraryDataService
只是另一个实现UITableViewDataSource
和UITableViewDelegate
类,区别在于情节@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.