2

我是swift新手,在PlacesTableViewController類中聲明我的初始化器時出現問題。它提示我,當我加入Super.init,它會提示我「Super.init不是從初始化返回之前被稱爲」:如何解決UITableViewController指定的初始化錯誤?

"Must call a designated initializer of the superclass '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 
    } 

} 
+0

規則很複雜,但一旦你理解它們就顯而易見。閱讀Swift語言書。它解釋了一切。 – gnasher729

+0

我查看過你的文件,你指定的初始化程序問題已解決,但是這導致了另一個錯誤:屬性'self.et'未在super.init調用時初始化。所以你的ety:Entry需要被正確地初始化。你可能應該問一個關於這個問題的新問題,因爲一般的做法是每個帖子提出一個問題。 –

+0

所以現在剩下的問題只是正確地初始化我的ety:Entry,我可以繼續使用我與你共享的代碼(要調試)嗎? 非常感謝您的幫助。 –

回答

1

查看這是否解決您的問題:

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 Class Reference

從斯威夫特編程語言指南:

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]


更新:

上面的代碼實際上解決了您的指定初始化程序的問題。您現在需要正確初始化您的self.ety屬性。

+0

覆蓋的init(風格:UITableViewStyle){ } // 錯誤:COpaquePointer,selectStatement:COpaquePointer,chapterdata:數組,ETY:入門,的SqlString Super.init不能從初始化 的init(pa55DB返回之前調用:字符串){ super.init(樣式:UITableViewStyle.Plain) self.pa55DB = pa55DB self.selectStatement = selectStatement self.chapterdata = chapterdata self.ety = ETY self.sqlString =的SqlString } //錯誤在super.init(風格:UITableViewStyle.Plain) - >屬性'自我.et'沒有初始化super.init調用 –

+0

你需要在你的初始化程序中更新你的super.init,將super.init(style:UITableViewStyle.Plain)添加到你的init(pa55DB ... –

+0

對不起,但是是不是super.init(樣式:UITableViewStyle.Plain)已經添加在你上面顯示的代碼中? –

4

init mess是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") 
    } 

    // … 
} 
+0

但是,當我運行我的項目時,出現了一個致命的錯誤, coder :)尚未實現 線程1:EXC_BAD_INSTRUCTION(code = EXC_1386_INVOP,subcode = 0x0) –

+0

您是從故事板還是nib/xib文件加載視圖控制器?如果是,那麼您還必須實現'required init(編碼器:NSCoder)''正確,目前沒有實現。 – fluidsonic

+0

是的,我使用視圖控制器從我的故事板。提供所需的init(編碼器:NSCoder),是否有任何我可以關注的參考? –

0

也許嘗試這樣的事:

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) 
    } 

    // … 
} 
-1

的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根據您的需要來實現。

+0

什麼,這是迄今爲止我在Stackoverflow上看到的最糟糕的陳述之一。 UITableViewController應該比原始UITableView更頻繁地使用。爲什麼在這個世界上你會重新創造已經完成的事情。 – TheCodingArt

+0

直到你發現UITableViewController在Swift中真的是_bad笑話,甚至在iOS 8 iPad上是_crash_。 https://forums.developer.apple.com/thread/16621 – denkeni

+0

這是swift和objc之間的初始化程序問題,它絕不支持您的糟糕聲明。作爲一個多年從事應用程序開發的用戶,Uber的用戶規模已經很大,如果你把一個uitableviewcontroller稱爲笑話大聲笑,我永遠不會認真對待你。對我而言,這聽起來就像你只是站出來一樣,不知道如何使用它或者具有不良的建築模式。另外,我建議在指責類實現之前查看問題報告。 – TheCodingArt

相關問題