xcode 何时在 Swift 中初始化委托
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32574047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to init a delegate in Swift
提问by JoeBayLD
I have a basic question. I'm working on a project with many delegate patterns, and would like reference on the best way about initializing them..
我有一个基本问题。我正在处理一个具有许多委托模式的项目,并希望参考有关初始化它们的最佳方法。
Here's some ideas with a test delegate I made:
这是我制作的测试委托的一些想法:
Option 1:
选项1:
It fails because I'm initilizing the delegate to self before super.init()
它失败了,因为我在 super.init() 之前将委托初始化为 self
protocol MyClassDelegate {
func doSomething()
}
class MyClass {
var delegate: MyClassDelegate!
init(delegate: MyClassDelegate){
self.delegate = delegate
}
func myClassFuction(){
self.delegate.doSomething()
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
let myClass: MyClass
override init(){
myClass = MyClass(delegate: self) // Error because it's called before super.init
super.init()
}
func doSomething(){
//called from the delegate
}
}
Option 2:
选项 2:
It works, but then I risk having the delegate be nil.. Would I have to run a 'if delegate != nil' check each time I want to call a method? Is there a way around that? Is it a good practice to init the delegate this way?
它有效,但是我冒着让委托为零的风险..每次我想调用一个方法时,我是否都必须运行“if delegate != nil”检查?有没有办法解决这个问题?以这种方式初始化委托是一个好习惯吗?
protocol MyClassDelegate {
func doSomething()
}
class MyClass {
var delegate: MyClassDelegate!
init(){
}
func myClassFuction(){
self.delegate.doSomething() // might fail if delegate is nil
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
let myClass: MyClass
override init(){
myClass = MyClass()
super.init()
myClass.delegate = self // works because called after super.init
}
func doSomething(){
//called from the delegate
}
}
Those were just a couple ideas. I'm just trying to learn the best way of doing it. I'm open to all suggestions.
这些只是一些想法。我只是想学习最好的方法。我愿意接受所有建议。
Thanks!!
谢谢!!
回答by vinn
Option 2 looks better. However, in this case it would be advisable to use an optional as your delegate type. That way, you don't need to check "if delegate != nil" every time you want to perform a task with it. You can simply use optional chaining, which is designed specifically for such cases where you want to perform a task on an optional only if it contains a value.
选项 2 看起来更好。但是,在这种情况下,建议使用 optional 作为您的委托类型。这样,每次要使用它执行任务时,您都不需要检查“if delegate != nil”。您可以简单地使用可选链,它是专门为这样的情况而设计的,即您希望仅当它包含一个值时才对它执行任务。
protocol MyClassDelegate {
func doSomething()
}
class MyClass {
var delegate: MyClassDelegate?
init(){
}
func myClassFuction(){
self.delegate?.doSomething() // will do nothing if delegate is nil
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
let myClass: MyClass
override init(){
myClass = MyClass()
super.init()
myClass.delegate = self
}
func doSomething(){
//called from the delegate
}
}
回答by Mecki
Use lazy initialization to work around that issue.
使用延迟初始化来解决该问题。
protocol MyClassDelegate: class {
func doSomething()
}
class MyClass {
private(set) weak var delegate: MyClassDelegate?
func myClassFuction ( ) {
self.delegate?.doSomething()
}
init ( delegate: MyClassDelegate ) {
self.delegate = delegate
}
}
class ClassConformingToDelegate: NSObject, MyClassDelegate {
lazy private(set) var myClass: MyClass = {
return MyClass(delegate: self)
}()
func doSomething ( ) {
//called from the delegate
}
}
The variable myClass
, which has no public setter, will be initialized the first time it is accessed by ClassConformingToDelegate
itself or by some external code. If you want to make sure that it is always initialized when creating a new ClassConformingToDelegate
object (as its sole creation may have side effects, like registration to notifications and so on), just access it from init
:
myClass
没有公共 setter的变量将在第一次被ClassConformingToDelegate
自身或某些外部代码访问时被初始化。如果您想确保在创建新ClassConformingToDelegate
对象时始终对其进行初始化(因为它的唯一创建可能有副作用,例如注册到通知等),只需从init
以下位置访问它:
override
init ( ) {
super.init()
_ = self.myClass
}