在 CustomUIView 中覆盖 init() 会导致应用程序崩溃(EXC_BAD ACCESS)
Overriding init() in a CustomUIView crashes app (EXC_BAD ACCESS)
我正在尝试在 Swift 中子class 一个 UIView。
调用初始化程序时应用程序崩溃 (EXC_BAD_ACCESS) 的方式
这是class
class CustomActionSheet: UIView {
private var cancelButtonTitle: String!;
private var destructiveButtonTitle: String!;
private var otherButtonTitles: [String]!;
convenience init() {
self.init();//EXC_BAD_ACCESS
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder);
}
convenience init(cancelButtonTitle: String!, destructiveButtonTitle: String!, otherButtonTitles: [String]!) {
self.init();
self.cancelButtonTitle = cancelButtonTitle;
self.destructiveButtonTitle = destructiveButtonTitle;
self.otherButtonTitles = otherButtonTitles;
prepareUI();
}
func prepareUI() {
//BLABLABLABLABLA
}
}
我是这样称呼它的
var actionSheet: CustomActionSheet = CustomActionSheet(cancelButtonTitle: "Cancel", destructiveButtonTitle: "OK", otherButtonTitles: nil);
试图用 super.init() 替换 self.init() 但无法编译。
错误信息:
Must call a designated initializer of the superclass 'UIView'
Convenience initializer for 'CustomActionSheet' must delegate (with 'self.init') rather than chaining to a superclass initializer (with 'super.init')
你需要用一个框架初始化你的 UIVIew,即使它是零,你也需要覆盖 init 以便你可以在调用晚餐之前初始化你的变量:
class CustomActionSheet: UIView {
private var cancelButtonTitle: String!;
private var destructiveButtonTitle: String!;
private var otherButtonTitles: [String]!;
override init(frame: CGRect) {
cancelButtonTitle = String()
destructiveButtonTitle = String()
otherButtonTitles: [String]()
super.init(frame:frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder);
}
convenience init(cancelButtonTitle: String!, destructiveButtonTitle: String!, otherButtonTitles: [String]!) {
self.init(frame: CGRectZero)
self.cancelButtonTitle = cancelButtonTitle;
self.destructiveButtonTitle = destructiveButtonTitle;
self.otherButtonTitles = otherButtonTitles;
prepareUI();
}
}
注意我删除了你创建的其他便利初始化器,因为你所有的变量都是私有的,所以不需要这个初始化器,但是如果你想要一个空的初始化器,你可以添加为:
convenience init() {
self.init(frame: CGRectZero)
}
也可以传递或修复框架的大小,您只需要进行适当的更改并调用 init(frame: yourFrame)
来自 Apple Documentation 的初始化规则:
Rule 1 A designated initializer must call a designated initializer
from its immediate superclass.
Rule 2 A convenience initializer must call another initializer from
the same class.
Rule 3 A convenience initializer must ultimately call a designated
initializer.
A simple way to remember this is:
Designated initializers must always delegate up. Convenience
initializers must always delegate across.
希望对你有帮助!
我正在尝试在 Swift 中子class 一个 UIView。
调用初始化程序时应用程序崩溃 (EXC_BAD_ACCESS) 的方式
这是class
class CustomActionSheet: UIView {
private var cancelButtonTitle: String!;
private var destructiveButtonTitle: String!;
private var otherButtonTitles: [String]!;
convenience init() {
self.init();//EXC_BAD_ACCESS
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder);
}
convenience init(cancelButtonTitle: String!, destructiveButtonTitle: String!, otherButtonTitles: [String]!) {
self.init();
self.cancelButtonTitle = cancelButtonTitle;
self.destructiveButtonTitle = destructiveButtonTitle;
self.otherButtonTitles = otherButtonTitles;
prepareUI();
}
func prepareUI() {
//BLABLABLABLABLA
}
}
我是这样称呼它的
var actionSheet: CustomActionSheet = CustomActionSheet(cancelButtonTitle: "Cancel", destructiveButtonTitle: "OK", otherButtonTitles: nil);
试图用 super.init() 替换 self.init() 但无法编译。
错误信息:
Must call a designated initializer of the superclass 'UIView'
Convenience initializer for 'CustomActionSheet' must delegate (with 'self.init') rather than chaining to a superclass initializer (with 'super.init')
你需要用一个框架初始化你的 UIVIew,即使它是零,你也需要覆盖 init 以便你可以在调用晚餐之前初始化你的变量:
class CustomActionSheet: UIView {
private var cancelButtonTitle: String!;
private var destructiveButtonTitle: String!;
private var otherButtonTitles: [String]!;
override init(frame: CGRect) {
cancelButtonTitle = String()
destructiveButtonTitle = String()
otherButtonTitles: [String]()
super.init(frame:frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder);
}
convenience init(cancelButtonTitle: String!, destructiveButtonTitle: String!, otherButtonTitles: [String]!) {
self.init(frame: CGRectZero)
self.cancelButtonTitle = cancelButtonTitle;
self.destructiveButtonTitle = destructiveButtonTitle;
self.otherButtonTitles = otherButtonTitles;
prepareUI();
}
}
注意我删除了你创建的其他便利初始化器,因为你所有的变量都是私有的,所以不需要这个初始化器,但是如果你想要一个空的初始化器,你可以添加为:
convenience init() {
self.init(frame: CGRectZero)
}
也可以传递或修复框架的大小,您只需要进行适当的更改并调用 init(frame: yourFrame)
来自 Apple Documentation 的初始化规则:
Rule 1 A designated initializer must call a designated initializer from its immediate superclass.
Rule 2 A convenience initializer must call another initializer from the same class.
Rule 3 A convenience initializer must ultimately call a designated initializer.
A simple way to remember this is:
Designated initializers must always delegate up. Convenience initializers must always delegate across.
希望对你有帮助!