问题
I'm new to swift and I'm having problems declaring my initializer in my PlacesTableViewController class. It prompts me "Super.init isn't called before returning from initializer" and when I added the Super.init, it prompts me:
"Must call a designated initializer of the superclass 'UITableViewController'"
this is my PlacesTableViewController.swift file:
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...")
}
...
}
Here's my another class file called ChapterData.swift, used to open database and retrieve data
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
}
}
回答1:
The init mess is a known limitation of the ObjC <-> Swift bridging.
One way to work around this is to delegate to super's init(nibName:bundle:) initializer.
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")
}
// …
}
回答2:
See if this resolves your issue:
override init(style: UITableViewStyle) {
super.init(style: style)
}
init(pa55DB : COpaquePointer,selectStatement : COpaquePointer, chapterdata : Array<Entry>, ety : Entry, sqlString : String) {
super.init(style: UITableView.Style.plain)
self.pa55DB = pa55DB
self.selectStatement = selectStatement
self.chapterdata = chapterdata
self.ety = ety
self.sqlString = sqlString
}
UITableView Class Reference
From the Swift Programming Language Guide:
Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.
[read more]
Update:
The above code actually resolves the issue with your designated initializer. You now need to properly initialize your self.ety property.
回答3:
Maybe try something like this:
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)
}
// …
}
回答4:
UITableViewController isn't anything good for advanced use cases. You can always subclass UIViewController and put an UITableView property in it, just like this:
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'"
}
}
And it works like UITableViewController.
Other utilities UITableViewController provides, like refreshControl you can also set one for yourself, like clearsSelectionOnViewWillAppear mechanism can also be implemented in viewWillAppear() or didSelectRowAtIndexPath depending on your needs.
来源:https://stackoverflow.com/questions/30316021/how-to-resolve-designated-initialization-error-for-uitableviewcontroller