如何解决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桥接的已知限制。
解决这个问题的一种方法是委托给super
的init(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
实现。