【问题标题】:Whats wrong with my convenience initializer when I attempt to call self.init?当我尝试调用 self.init 时,我的便利初始化程序有什么问题?
【发布时间】:2018-04-26 22:40:43
【问题描述】:

我写了下面的代码。当我尝试调用 self.init 时,我得到的错误出现在我的便利初始化程序的末尾。我的逻辑或语法有什么问题?或者我将如何调试这个? Xcode 给出的错误是“不能使用类型的参数列表调用”。

感谢您对此的任何帮助

import Foundation
import UIKit

class Item: NSObject {

    var name: String
    var valueInDollars: Int
    var serialNumber: String?
    let dateCreated: NSDate
    var stolen: Bool?

    init(name: String, valueInDollars: Int, serialNumber: String?, dateCreated: NSDate, stolen: Bool?) {
        self.name = name
        self.valueInDollars = valueInDollars
        self.serialNumber = serialNumber
        self.dateCreated = NSDate()
        self.stolen = stolen

        //below why did I have to call super.init for this custom class that inherits from NSObject? Doesn't it automatically get called anyway once the custom object is initialized since it inherits from NSObject?  It just seems like more work on my behalf which isn't fair.  it should do it automatically.  Why wouldn't it do it automatically if it inherits from NSObject?
        super.init()
    }

    convenience init(random: Bool = false) {
        if random {
            let adjectives = ["Fluffy", "Rusty", "Shiny"]
            let nouns = ["MacBook Pro", "Red Tribe Bike", "Vegan Pizzas"]
            //take a variable that's random; the highest value for this random number will be the number of ojbects in the adjectives array
            var idx = arc4random_uniform(UInt32(adjectives.count))
            //now use this random variable and let it be the index of the adjectives array...so basically it'll be a random object from the adjectives array
            let randomAdjective = adjectives[Int(idx)]

            //AWESOME!! Now that the random adjective is stored in the randomAdjective constant, let's re-use the idx variable...Ayyyyeeeee re-use!

            //we'll re-use it by doing the same process or close to the same process for nouns
            idx = arc4random_uniform(UInt32(nouns.count))
            let randomNoun = nouns[Int(idx)]

            //now let's concatenate these two clever words, shall we!!
            let randomName = "\(randomAdjective) \(randomNoun)"

            //yayyy we're programmmminnngg!

            //now let's ....whad de fuk....
            let randomValue = Int(arc4random_uniform(100))
            let randomSerialNumber = NSUUID().uuidString.components(separatedBy: "-").first!

            let betterNotBeStolen: Bool = false

            self.init(name: randomName, valueInDollars: randomValue, serialNumber: randomSerialNumber, stolen: betterNotBeStolen)


        }
    }
}

【问题讨论】:

  • 看看你的init方法。您忘记传递其中一个参数。

标签: swift initialization convenience-methods


【解决方案1】:

你得到了错误

"不能使用类型为 '(name: String, valueInDollars: Int, serialNumber: String,被盗: Bool)'"

因为您错过了 self.init(params...) 中的 dateCreated 参数。

所以你需要替换这一行

self.init(name: randomName, valueInDollars: randomValue, serialNumber: randomSerialNumber, stolen: betterNotBeStolen)

这个

self.init(name: randomName, valueInDollars: randomValue, serialNumber: randomSerialNumber,dateCreated: NSDate(), stolen: betterNotBeStolen)

您将看到的下一个错误是

在从初始化程序返回之前,不会在所有路径上调用 Self.init

所以你需要添加 else 语句,因为初始化器不知道当随机参数为 false 时该怎么做。

convenience init(random: Bool = false) {
        if random {
            let adjectives = ["Fluffy", "Rusty", "Shiny"]
            let nouns = ["MacBook Pro", "Red Tribe Bike", "Vegan Pizzas"]
            //take a variable that's random; the highest value for this random number will be the number of ojbects in the adjectives array
            var idx = arc4random_uniform(UInt32(adjectives.count))
            //now use this random variable and let it be the index of the adjectives array...so basically it'll be a random object from the adjectives array
            let randomAdjective = adjectives[Int(idx)]

            //AWESOME!! Now that the random adjective is stored in the randomAdjective constant, let's re-use the idx variable...Ayyyyeeeee re-use!

            //we'll re-use it by doing the same process or close to the same process for nouns
            idx = arc4random_uniform(UInt32(nouns.count))
            let randomNoun = nouns[Int(idx)]

            //now let's concatenate these two clever words, shall we!!
            let randomName = "\(randomAdjective) \(randomNoun)"

            //yayyy we're programmmminnngg!

            //now let's ....whad de fuk....
            let randomValue = Int(arc4random_uniform(100))
            let randomSerialNumber = NSUUID().uuidString.components(separatedBy: "-").first!

            let betterNotBeStolen: Bool = false

            self.init(name: randomName, valueInDollars: randomValue, serialNumber: randomSerialNumber,dateCreated: NSDate(), stolen: betterNotBeStolen)


        } else {

           self.init(name: "SomeName", valueInDollars: 3, serialNumber: "123", dateCreated: NSDate(), stolen: true)
        }
    }

【讨论】:

  • 1.您的答案解决了他们在问题中发布的代码中解决问题后将发生的新错误。 2. 不要在Swift中使用NSDate,使用Date
  • @rmaddy 1.错误是什么? 2.NSDate用于指定初始化器,为了避免强制转换我使用了NSDate初始化,我同意你没有理由使用NSDate。
  • 问题中的错误是在便捷初始化程序中将错误的参数传递给self.init(...
  • @CosmicArrows NSDate(以及许多其他NS* 类)适用于Objective-C。 Swift 提供了Date(以及许多其他非 NS 类/结构的替换)。
  • @CosmicArrows 请阅读 Swift 书中的Initialization 章节。专注于“类继承和初始化”部分。便利初始化程序必须调用 self 初始化程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 2016-01-17
相关资源
最近更新 更多