覆盖CustomUIView中的init()崩溃应用程序(EXC_BAD ACCESS) [英] Overriding init() in a CustomUIView crashes app (EXC_BAD ACCESS)

查看:136
本文介绍了覆盖CustomUIView中的init()崩溃应用程序(EXC_BAD ACCESS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Swift中继承UIView。

I am trying to subclass a UIView in Swift.

调用初始值设定项时应用程序崩溃(EXC_BAD_ACCESS)

Howver the app crashes (EXC_BAD_ACCESS) when the initializer is called

这是类

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);






试图替换自我.init()with super.init()但它不会编译。


Tried to replace self.init() with super.init() but it won't compile.

错误消息:


必须调用超类'UIView'的指定初始值设定项

Must call a designated initializer of the superclass 'UIView'

'CustomActionSheet'的便捷初始化程序必须委托(使用'self.init')而不是链接到超类初始值设定项(使用'super.init')

Convenience initializer for 'CustomActionSheet' must delegate (with 'self.init') rather than chaining to a superclass initializer (with 'super.init')


推荐答案

你需要用一个帧来初始化你的UIVIew,即使它是零,你还需要覆盖init,这样你就可以在调用supper之前初始化你的变量:

You need to initializer your UIVIew with a frame, even if it is zero, you also need to override the init so you can initialize your variables before call supper:

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();
    }
}

注意我删除了你创建的其他便利初始值设定项你的变量是私有的,不需要这个初始化程序,但是如果你想要一个空的初始化程序,你可以添加为:

Notice I remove the other convenience initializer you create given all your variables are private there is no need to this initializer, however if you want to have an empty initializer you can just add as:

convenience init() {
    self.init(frame: CGRectZero)
}

还可以传递帧的大小或修复你只需要进行适当的更改并调用 init(frame:yourFrame)

Also the size of the frame can be passed or fix you just need to make the appropriate changes and call init(frame: yourFrame)

Apple文档初始化规则


规则1指定的初始化程序必须从其直接超类中调用指定的初始化程序

Rule 1 A designated initializer must call a designated initializer from its immediate superclass.

规则2一个便利初始化程序必须从同一个类的
调用另一个初始化程序。

Rule 2 A convenience initializer must call another initializer from the same class.

规则3便利初始化程序必须最终调用指定的
初始化程序。

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.

我希望能帮到你!

这篇关于覆盖CustomUIView中的init()崩溃应用程序(EXC_BAD ACCESS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆