[英]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.