Chi*_*Pan 59 initialization convenience-methods swift
我很难理解两者之间的区别,或者方便init的目的.谢谢
tre*_*son 81
标准init:
指定的初始值设定项是类的主要初始值设定项.指定的初始化程序完全初始化该类引入的所有属性,并调用适当的超类初始化程序以继续超类链的初始化过程.
convenience init:
便利初始化程序是次要的,支持类的初始化程序.您可以定义一个便捷初始值设定项,以便从与便捷初始化程序相同的类中调用指定的初始值设定项,并将某些指定的初始值设定项参数设置为默认值.您还可以定义一个便捷初始值设定项,以便为特定用例或输入值类型创建该类的实例.
根据Swift文档
基本上所有这一切都意味着你使用一个方便的初始化程序来更快,更"方便"地调用指定的初始化程序.因此,便利初始化程序需要使用self.init而不是像在super.init指定初始化程序的覆盖中看到的那样.
伪代码示例:
init(param1, param2, param3, ... , paramN) {
// code
}
// can call this initializer and only enter one parameter,
// set the rest as defaults
convenience init(myParamN) {
self.init(defaultParam1, defaultParam2, defaultParam3, ... , myParamN)
}
Run Code Online (Sandbox Code Playgroud)
我在创建自定义视图时使用了很多这样的视图,并且使用主要是默认值的长初始化程序.文档比我更好地解释,检查出来!
Mag*_*ios 53
当你有一些具有很多属性的类时会使用便利初始化程序,这使得总是用所有变量初始化机智有点"痛苦",所以你使用便利初始化程序做的是你只需传递一些变量来初始化对象,并为其余部分分配默认值.Ray Wenderlich网站上有一个非常好的视频,不确定它是否免费,因为我有一个付费帐户.这是一个例子,你可以看到,而不是用所有这些变量初始化我的对象我只是给它一个标题.
struct Scene {
var minutes = 0
}
class Movie {
var title: String
var author: String
var date: Int
var scenes: [Scene]
init(title: String, author: String, date: Int) {
self.title = title
self.author = author
self.date = date
scenes = [Scene]()
}
convenience init(title:String) {
self.init(title:title, author: "Unknown", date:2016)
}
func addPage(page: Scene) {
scenes.append(page)
}
}
var myMovie = Movie(title: "my title") // Using convenicence initializer
var otherMovie = Movie(title: "My Title", author: "My Author", date: 12) // Using a long normal initializer
Run Code Online (Sandbox Code Playgroud)
dir*_*nee 11
这是一个简单的例子,取自Apple Developer门户网站.
基本上,指定的初始化程序是init(name: String),它确保初始化所有存储的属性.
的init()方便初始化,服用任何参数,全自动的值设置name存储属性[Unnamed]通过使用指定的初始化.
class Food {
let name: String
// MARK: - designated initializer
init(name: String) {
self.name = name
}
// MARK: - convenience initializer
convenience init() {
self.init(name: "[Unnamed]")
}
}
// MARK: - Examples
let food = Food(name: "Cheese") // name will be "Cheese"
let food = Food() // name will be "[Unnamed]"
Run Code Online (Sandbox Code Playgroud)
当您处理大型类时,至少有一些存储属性是很有用的.我建议在Apple Developer门户网站上阅读更多关于选项和继承的内容.
对我来说,convenience initializers如果除了简单地为类属性设置默认值之外,还有更多事情要做,则很有用。
否则,我只会在init定义中设置默认值,例如:
class Animal {
var race: String // enum might be better but I am using string for simplicity
var name: String
var legCount: Int
init(race: String = "Dog", name: String, legCount: Int = 4) {
self.race = race
self.name = name
self.legCount = legCount // will be 4 by default
}
}
Run Code Online (Sandbox Code Playgroud)
但是,除了简单地设置默认值之外,可能还有更多事情要做,这就是convenience initializers派上用场的地方:
extension Animal {
convenience init(race: String, name: String) {
var legs: Int
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
} else {
fatalError("Race \(race) needs to be implemented!!")
}
// will initialize legCount automatically with correct number of legs if race is implemented
self.init(race: race, name: name, legCount: legs)
}
}
Run Code Online (Sandbox Code Playgroud)
// default init with all default values used
let myFirstDog = Animal(name: "Bello")
// convenience init for Spider as race
let mySpider = Animal(race: "Spider", name: "Itzy")
// default init with all parameters set by user
let myOctopus = Animal(race: "Octopus", name: "Octocat", legCount: 16)
// convenience init with Fatal error: Race AlienSpecies needs to be implemented!!
let myFault = Animal(race: "AlienSpecies", name: "HelloEarth")
Run Code Online (Sandbox Code Playgroud)
如果您的用例是在同一类中的另一个初始化程序中调用初始化程序,这是有道理的。
尝试在操场上这样做
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
init(name: String) {
self.init(name: name, level: 0) //<- Call the initializer above?
//Sorry you can't do that. How about adding a convenience keyword?
}
}
Player(name:"LoseALot")
Run Code Online (Sandbox Code Playgroud)
带方便关键字
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
//Add the convenience keyword
convenience init(name: String) {
self.init(name: name, level: 0) //Yes! I am now allowed to call my fellow initializer!
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想通过扩展类型为类型创建自己的自定义初始值设定项,这也很有用。
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
}
extension Player {
convenience init(name: String) {
self.init(name: name, level: 0)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31055 次 |
| 最近记录: |