如何解决UITableViewController指定的初始化错误?

我是新来的swift,我有问题在我的PlacesTableViewController类中声明我的初始值设定项。 它提示我“从初始化程序返回之前不会调用Super.init”,当我添加Super.init时,它会提示我:

“必须调用超类'UITableViewController'的指定初始值设定项”

这是我的PlacesTableViewController.swift文件:

class PlacesTableViewController: UITableViewController { var pa55DB : COpaquePointer = nil var selectStatement : COpaquePointer = nil; var chapterdata : Array<Entry> = [] var ety : Entry var sqlString : String = ""; var chpData : ChapterData init(pa55DB : COpaquePointer,selectStatement : COpaquePointer, chapterdata : Array<Entry>, ety : Entry, sqlString : String) { super.init() self.pa55DB = pa55DB self.selectStatement = selectStatement self.chapterdata = chapterdata self.ety = ety self.sqlString = sqlString } required init!(coder aDecoder: NSCoder!) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() chpData = ChapterData(newEntryArray : chapterdata, entryV : ety, paDB55 : pa55DB, selectStatement : selectStatement, sqlString : sqlString) chpData.openDB() chapterdata = chpData.prepareStartment() println("Testing...") } ... } 

这是我的另一个名为ChapterData.swift的类文件,用于打开数据库和检索数据

 class Entry { let image : String! let heading : String! let title : String! let description : String! public init(image : String, heading : String, title : String, desc : String) { self.heading = heading self.image = image self.title = title self.description = desc } } class ChapterData { var paDB : COpaquePointer = nil; var selectStatement : COpaquePointer = nil; var sqlString : String = ""; var newEntryArray : Array<Entry> = []; var entryV : Entry; init(newEntryArray : Array<Entry>, entryV : Entry, paDB55 : COpaquePointer, selectStatement : COpaquePointer, sqlString : String){ self.newEntryArray = newEntryArray self.entryV = entryV self.paDB = paDB55 self.selectStatement = selectStatement self.sqlString = sqlString } func openDB() { var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String var docsDir = paths.stringByAppendingPathComponent("pa55.sqlite") if (sqlite3_open(docsDir, &paDB) == SQLITE_OK) { println("success open database") } else { println("failed to open database") } } func prepareStartment() -> Array<Entry> { sqlString = "SELECT * FROM Chapter ORDER BY CID ASC" var cSql = sqlString.cStringUsingEncoding(NSUTF8StringEncoding) sqlite3_prepare_v2(paDB, cSql!, -1, &selectStatement, nil) println("startment start") while (sqlite3_step(selectStatement) == SQLITE_ROW) { let image_buf = sqlite3_column_text(selectStatement, 3) var image = String.fromCString(UnsafePointer<CChar>(image_buf)) let heading_buf = sqlite3_column_text(selectStatement, 1) var heading = String.fromCString(UnsafePointer<CChar>(heading_buf)) let title_buf = sqlite3_column_text(selectStatement, 2) var title = String.fromCString(UnsafePointer<CChar>(title_buf)) let desc_buf = sqlite3_column_text(selectStatement, 4) var description = String.fromCString(UnsafePointer<CChar>(desc_buf)) entryV = Entry(image: image!, heading: heading!, title: title!, desc: description!) newEntryArray.append(entryV) } println("select statement successful executed") return newEntryArray } } 

init混乱是ObjC < – > Swift桥接的已知限制。

解决这个问题的一种方法是委托给superinit(nibName:bundle:)初始化器。

 class PlacesTableViewController: UITableViewController { var chapterdata: [Entry] var chpData: ChapterData? var ety: Entry var pa55DB: COpaquePointer var selectStatement: COpaquePointer var sqlString: String init(pa55DB: COpaquePointer, selectStatement: COpaquePointer, chapterdata: [Entry], ety: Entry, sqlString: String) { self.pa55DB = pa55DB self.selectStatement = selectStatement self.chapterdata = chapterdata self.ety = ety self.sqlString = sqlString super.init(nibName: nil, bundle: nil) } required init(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // … } 

看看这是否解决您的问题:

 override init(style: UITableViewStyle) { super.init(style: style) } init(pa55DB : COpaquePointer,selectStatement : COpaquePointer, chapterdata : Array<Entry>, ety : Entry, sqlString : String) { super.init(style: UITableViewStyle.Plain) self.pa55DB = pa55DB self.selectStatement = selectStatement self.chapterdata = chapterdata self.ety = ety self.sqlString = sqlString } 

UITableView类参考

从Swift编程语言指南:

指定的初始化程序是一个类的主要初始化程序。 指定的初始化程序完全初始化由该类引入的所有属性,并调用适当的超类初始化程序以继续超类链的初始化过程。

[阅读更多]


更新:

上面的代码实际上解决了您指定的初始化程序的问题。 您现在需要正确初始化您的self.ety属性。

也许尝试这样的事情:

 class PlacesTableViewController: UITableViewController { var chapterdata: [Entry] var chpData: ChapterData? var ety: Entry var pa55DB: COpaquePointer var selectStatement: COpaquePointer var sqlString: String convenience init(pa55DB: COpaquePointer, selectStatement: COpaquePointer, chapterdata: [Entry], ety: Entry, sqlString: String) { self.init() self.pa55DB = pa55DB self.selectStatement = selectStatement self.chapterdata = chapterdata self.ety = ety self.sqlString = sqlString } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } // … } 

对于高级用例,UITableViewController并不是什么好东西。 你总是可以UIViewController并在其中放置一个UITableView属性,就像这样:

 class PlacesTableViewController: UIViewController { let tableView = UITableView(frame: CGRectZero, style: .Plain) override func loadView() { view = tableView } // Custom designated initializer init(pa55DB : COpaquePointer,selectStatement : COpaquePointer, chapterdata : Array<Entry>, ety : Entry, sqlString : String) { // setting up these properties super.init(nibName: nil, bundle: nil) // designated initializer of the superclass 'UIViewController'" } } 

它和UITableViewController一样工作。

UITableViewController提供的其他实用工具,如refreshControl您也可以为自己设置一个,如clearsSelectionOnViewWillAppear机制,也可以根据需要在viewWillAppear()didSelectRowAtIndexPath实现。