2015-06-12 17 views
8

Tôi đang cố gắng phân lớp UIView trong Swift.Ghi đè init() trong ứng dụng bị lỗi CustomUIView (EXC_BAD ACCESS)

Howver treo ứng dụng (EXC_BAD_ACCESS) khi khởi tạo được gọi là

Đây là lớp

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 
    } 
} 

Dưới đây là làm thế nào tôi gọi nó

var actionSheet: CustomActionSheet = CustomActionSheet(cancelButtonTitle: "Cancel", destructiveButtonTitle: "OK", otherButtonTitles: nil); 

thử để thay thế self.init() bằng super.init() nhưng nó sẽ không co mpile.

Thông báo Lỗi:

Phải gọi một initializer được chỉ định của lớp cha 'UIView'

Thuận tiện initializer cho 'CustomActionSheet' phải ủy thác (với 'self.init') chứ không phải là chaining được kết tới một trình khởi tạo siêu lớp (với 'super.init')

+1

Ý của bạn là đặt super.init() vào vị trí có lỗi? – spektr

+0

super.init() thậm chí không biên dịch @choward. Tôi đã cập nhật câu hỏi của mình. – JayVDiyk

Trả lời

7

Bạn cần khởi tạo UIVIew của bạn với khung, ngay cả khi nó bằng 0, bạn cũng cần ghi đè init để bạn có thể nitialize biến của bạn trước khi bữa ăn tối gọi:

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

Thông báo tôi loại bỏ các initializer tiện khác bạn tạo cho tất cả các biến của bạn là cá nhân không có nhu cầu để khởi tạo này, tuy nhiên nếu bạn muốn có một initializer trống bạn chỉ có thể thêm như:

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

Ngoài ra kích thước của khung có thể được thông qua hoặc sửa chữa, bạn chỉ cần thực hiện những thay đổi thích hợp và gọi init(frame: yourFrame)

Nội quy để khởi tạo từ Apple Documentation:

Quy tắc 1 Trình khởi tạo được chỉ định phải gọi trình khởi tạo được chỉ định từ siêu lớp ngay lập tức.

Quy tắc 2 Trình khởi tạo thuận tiện phải gọi một trình khởi tạo khác từ cùng một lớp.

Quy tắc 3 Trình khởi tạo thuận tiện cuối cùng phải gọi một trình khởi tạo được chỉ định.

Cách đơn giản để ghi nhớ điều này là:

Trình khởi tạo được chỉ định phải luôn ủy quyền. Thuận tiện công cụ khởi tạo phải luôn ủy quyền trên toàn bộ.

enter image description here

Tôi hy vọng rằng sẽ giúp bạn!

+0

Thanksss, nó hoạt động – JayVDiyk

+1

Tôi vui vì nó hoạt động, tôi sẽ thêm một chút chi tiết hơn về tôi cũng đã có một thời gian thực sự khó khăn lần đầu tiên tôi cố gắng kế thừa từ UIView. Chúc may mắn trong ứng dụng của bạn! – Icaro

+0

Cảm ơn bạn đã giải thích kỹ lưỡng @Icaro – JayVDiyk

Các vấn đề liên quan