swift – 在super.init中引用self
我有以下代码(编辑:更新代码,以便每个人都可以编译并查看):
import UIKit struct Action { let text: String let handler: (() -> Void)? } class AlertView : UIView { init(actions: [Action]) { super.init(frame: .zero) for action in actions { // let actionButton = ActionButton(type: .custom) // actionButton.title = action.title // actionButton.handler = action.handler // addSubview(actionButton) } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class TextAlertView : AlertView { init() { super.init(actions: [ Action(text: "No",handler: nil),Action(text: "Yes",handler: { [weak self] in //use self in here.. }) ]) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class MyViewController : UIViewController { override func viewDidLoad() { super.viewDidLoad() let alert = TextAlertView() view.addSubview(alert) self.view = view } } 每次我实例化TextAlertView时,它都会在访问不良的super.init上崩溃.但是,如果我改变: Action(title: "Yes",{ [weak self] in //use self in here.. }) 至: Action(title: "Yes",{ //Blank.. doesn't reference `self` in any way (weak,unowned,etc) }) 有用! 在超级初始化期间有没有办法在动作块中引用自身弱或不弱(在上面我在super.init的参数中做它? 代码编译..它只是在运行时随机崩溃. 解决方法
简短回答:
在super.init返回之前,您无法捕获并使用self作为值.在你的情况下,你试图将自己“传递”为super.init作为参数. 根据第二部分的工作原理,仅仅因为没有使用自我,它不会捕捉自我,因此它不会将自我用作价值. 如果你不想在闭包中使用self,那么你不需要担心那里的强/弱引用,因为根本没有对self的引用(因为它没有被捕获).没有保留周期的危险. 关于“将自我用作值”的简短说明 – 您可以在赋值的左侧使用self来在初始化时引用self的属性: let myProperty: String init(with myProperty: String) { // this usage of self is allowed self.myProperty = myProperty super.init(nibName: nil,bundle: nil) } 更长的答案与参考和东西: 按照documentation:
第一阶段的初始化是通过调用super.init来结束的 从相同的文档:
因此,只有在调用super.init之后,才允许使用self作为值:
现在,当你尝试将self用作闭包捕获列表中的值时,我并不感到惊讶,它崩溃了.我更惊讶的是编译器允许你这样做 – 现在我想这是一个没有实现错误处理的边缘情况. 在第二种情况: Action(title: "Yes",etc) }) 你并没有真正捕捉到自我,这就是为什么它被允许并且它有效.但是你没有那里的自我.尝试添加一些使用self的代码,编译器会抱怨: 所以最后,如果你想在闭包中使用self,你必须找到一种方法,首先调用super.init,然后才能在属性中添加自捕获闭包. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |