在调用super.init之前使用self

26

我刚开始学习Swift,不太明白如何初始化一个类。

Succeeded在类定义中被初始化为false

if (succeeded && (time>1000)){
   errormessage += ";connection slow"
 }

时间被初始化为

time = data[3].toInt()

数据在哪里

var data = split(raw_data) {$0 == ","}

raw_data 是一个字符串。

类定义:

class geocodeObject: NSObject {

init 的定义:

init(lat: String,long:String,userstate:String) {

(没有超级初始化)

完整代码,已削减部分内容:

class geocodeObject: NSObject {
    //A type to store the data from the Reverse Geocoding API
    //Not a retriever
    
    //Options
    let API_KEY_TEXAS = "9e4797c018164fdcb9a95edf3b10ccfc"
    let DEV_MODE = true
    //Loading status
    var succeeded = false
    var errormessage = "Not Initalized" //Not nesscarilly a failure, could be slow connection
    var loadstate: String?
    //Most important info
    var street: String?; var housenumber: String?; var city: String?; var zip: String?
    //Metadata
    var time: IntegerLiteralType?; var statuscode: String?; var queryid: String?; var zip4: String?
    //Other geographical data
    var entirestreet: String?; var state: String?
    init(lat: String,long:String,userstate:String) {
        //userstate: State provided by user
        //state: State provided by Reverse Geocoder

        var url: String?
        var extra: String?
        if DEV_MODE{
            extra = "&notStore=true"
        }
        else{
            extra = ""
        }
        url = "http://geoservices.tamu.edu/Services/ReverseGeocoding/WebService/v04_01/HTTP/default.aspx?lat="+lat+"&lon="+long+"&apikey="+API_KEY_TEXAS+"&version=4.01"
        if (userstate == "nil"){
            url = url! + extra!
            println("if")
        }
        else{
            url = url! + "&state="+state!+extra!
            println("else")
        }
        
        let raw_data = retrieveurl(url!)
        var data = split(raw_data) {$0 == ","}
        //data[1] is API version used.
        statuscode = data[0]; queryid = data[2]; time = data[3].toInt(); entirestreet = data[4]; city = data[5]
        state = data[6]; zip = data[7]; zip4 = data[8]
        //Do street, housenumber, errormessage, succeeded
        if (state != userstate){
            println("user state not equal to state")
        }
        var splittedstreet = split(entirestreet!){$0 == " "}
        housenumber = splittedstreet[0]
        street = splittedstreet[1]
        println(statuscode)
        //Error message handling
        switch String(statuscode!){
            case "200":
                errormessage = "Success"
            case "400":
                errormessage = "Unknown API key error"
            case "401":
                ...
        //Time handling
        if (succeeded && (time>1000)){
            errormessage += ";connection slow"
        }
       }
        println("/GeocodingAPIWrapper.swift/.geocodeObject.init: Not Implemented")
    }
    
}

3
如果您将代码一次性发布并删去不必要的内容,阅读起来会更容易。 - qwerty_so
4
类名通常以大写字母开头。 - fred02138
2个回答

51

已经有一段时间了,但我找到的答案是,在您的init块内部的第一行添加super.init()。

init(lat: String,long:String,userstate:String) {
    super.init()
    ...

我通过这种方式摆脱了它并满足了错误要求的内容。 据我理解,这是因为在 NSObject.init() 过程中初始化了变量,因此您可以在定制的 init(_) 块中使用分配的值。


非常感谢。我最终放弃了那段代码,转而开始编写服务器,但现在我知道了。谢谢。 - noɥʇʎԀʎzɐɹƆ

34

Swift 2.2(截至撰写本文时仍为测试版)如果您意外忘记从guardelse返回nil,则会显示此错误:

required init?(dictionary: [String: AnyObject]) {

    guard let someValue = dictionary["someValue"] as? Bool else { return /*nil*/ } //Nil should not be commented here
    self.someValue = someValue

    super.init(dictionary: dictionary) //`self` used before super.init call
}

希望这能帮助到某些人


3
谢谢!那个错误让我抓狂了。尽管在我的情况下,我有一个便利初始化程序调用self.init() - HAS
同样的情况也会发生在没有return nilif let模式中。 - Oliver Cooper
非常感谢你,十万亿次。 - xaphod
2
这个问题在Swift 3中仍然存在!这是那种错误不是技术上误导人的情况之一,但更好的措辞会帮助很多。类似于“初始化程序结束时没有调用super.init()”的语句会为我节省大量时间。感谢您的提示。 - Bruno Philipe
1
@Jugale,实际上你的回答帮助了我解决问题!在我的情况下,不是所有可失败初始化器的路径都返回nil或实例...并且返回相同的错误,消息应该更明确!无论如何,谢谢! - cdescours
2
仍然发生在Swift 5中。 - mousebird

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接