2015-06-06 19 views
33

Tôi không thể thêm phương thức init vào lớp UIViewController sau đây. Tôi cần viết một số mã trong phương thức init. Tôi có phải viết phương thức init (coder) không? Ngay cả khi tôi thêm các phương pháp mã hóa và giải mã, tôi vẫn gặp lỗi. Tôi cũng đã thử bằng cách sử dụng phương pháp init mà không có bất kỳ tham số nhưng điều đó cũng không có vẻ làm việc.Cách viết phương thức init của UIViewController trong Swift

class ViewController: UIViewController { 

    var tap: UITapGestureRecognizer? 

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
     super.init(nibName: nil, bundle: nil) 
     tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) 
    } 

... 
... 
} 

Nếu tôi gọi phương thức super.init() không có tham số lỗi là "Phải gọi một initializer chỉ định của siêu lớp" và nếu tôi vượt qua các tham số nib và bó thì lỗi là "initializer init Required (coder) ".

Ngay cả khi tôi thêm init (coder) và init (bộ giải mã) nó không hoạt động.

+0

lỗi là gì? –

+0

bạn phải thử init bắt buộc. Tôi đã thêm câu trả lời @ankit –

+0

Chính xác thì bạn muốn thêm gì vào 'init()' của mình? Nếu nó chỉ là cử chỉ chạm, bạn có thể làm điều đó trong 'viewDidLoad()', hoặc thậm chí làm cho nó trở thành một biến thể lười biếng. – Eendje

Trả lời

4

Tôi nghĩ rằng bạn cần phải thêm

required init(coder aDecoder: NSCoder) { 
    print("init coder") 
    super.init(coder: aDecoder) 
} 

hoặc

convenience init() { 
    self.init() 
} 

Bạn phải viết init quá. Không tháo nó

var tap: UITapGestureRecognizer? 

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { 
    super.init(nibName: nil, bundle: nil) 
} 

Hy vọng nó giúp

+3

Điều này cho biết lỗi "Phải gọi một khởi tạo được chỉ định của siêu lớp" –

6

Bạn chỉ có thể tạo ra một initializer tiện thay vào đó, initializers tiện không ghi đè lên các init() thay vào đó nó chỉ gọi nó là làm cho mọi thứ dễ dàng hơn.

class ViewController: UIViewController { 
    var tap: UITapGestureRecognizer? 
    convenience init(){ 
     self.init() 
     tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) 
    } 
} 
+0

Ứng dụng bị lỗi vì nhấn là không mặc dù nó được gán giá trị trong init. –

+0

bạn đang cố gắng sử dụng nhấn từ một lớp khác? – Icaro

+0

nhấn được khai báo trong cùng một lớp .. giống như mã của bạn. –

37

tôi đã sử dụng:

convenience init() { 
    self.init(nibName:nil, bundle:nil) 
} 

Một số người đề nghị:

convenience init(){ 
    self.init() 
} 

Nhưng điều này mang đến cho bạn một vòng lặp vô hạn.

+1

Đây phải là câu trả lời đúng. –

+0

Tôi nhận được lỗi "Đối số được chuyển đến cuộc gọi không có đối số" trên câu lệnh "self.init (nibName: nil, bundle: nil)". – RenniePet

+0

Không được gọi bởi bộ điều khiển của tôi. – Jonny

13

Bạn cần phải ghi đè lên init(nibName:bundle:) initializer, cung cấp initializer init(coder:) yêu cầu, và khởi tap ở cả trong số họ:

class ViewController: UIViewController { 

    var tap: UITapGestureRecognizer? 

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 
     print("init nibName style") 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) 
    } 

    // note slightly new syntax for 2017 
    required init?(coder aDecoder: NSCoder) { 
     print("init coder style") 
     super.init(coder: aDecoder) 
     tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) 
    } 
... 
... 
} 

Ngoài ra, hãy chắc chắn khi gọi initializer lớp cha mà bạn không chỉ cần vượt qua nil cho số nibNamebundle. Bạn nên bỏ qua bất cứ điều gì đã được thông qua.

+2

Bên trong của 'init bắt buộc (coder aDecoder: NSCoder)', bạn có 'super.init()' ... không phải là 'super.init (coder: aDecoder)'? –

+0

Thực tế có hai lỗi chính tả tầm thường trong ví dụ mã. Bạn có thể thấy các lỗi chính tả dễ dàng chỉ bằng cách sử dụng tự động hoàn thành trong Xcode. Roman, nếu bạn thấy điều này, tôi đã chỉnh sửa lỗi chính tả. Tự nhiên thay đổi hoặc thư giãn. Đây là câu trả lời đúng duy nhất ở đây vì vậy tôi đã sửa lỗi chính tả, cổ vũ mọi người. – Fattie

12

Tất cả các câu trả lời này là một nửa câu trả lời. Một số người đang trải qua các vòng lặp vô hạn trong các bài đăng có liên quan vì họ chỉ thêm convenience init() (nó đệ quy gọi chính nó nếu bạn không cung cấp phương thức init() riêng biệt để gọi), trong khi những người khác đang bỏ qua để mở rộng siêu lớp. Định dạng này kết hợp tất cả các giải pháp để đáp ứng hoàn toàn vấn đề.

// This allows you to initialise your custom UIViewController without a nib or bundle. 
convenience init() { 
    self.init(nibName:nil, bundle:nil) 
} 

// This extends the superclass. 
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
    tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) 
} 

// This is also necessary when extending the superclass. 
required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") // or see Roman Sausarnes's answer 
} 

Edit: Ngoài ra, nếu bạn muốn khởi tạo bất kỳ thuộc tính lớp sử dụng các tham số được truyền vào phương pháp convenience init() bạn mà không cần tất cả các init() phương pháp ghi đè phàn nàn, sau đó bạn có thể thiết lập tất cả các thuộc tính như ngầm optionals nào, đó là một mẫu used by Apple themselves.

0

Tôi đã xem qua Câu hỏi về Bạn đã hỏi đường dài này Quay lại. Nhưng không ai cung cấp câu trả lời cơ bản cho câu hỏi. Cơ bản trong Swift là: - Lớp con phải khởi tạo các biến của nó trước khi khởi tạo siêu lớp hoàn tất.

Do đó như Ankit Goel đề cập đến vụ tai nạn: - "Phải gọi một initializer chỉ định của lớp cha"

cập nhật Do đó code sẽ là: -

class ViewController: UIViewController { 
var tap: UITapGestureRecognizer? 

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 
print("init nibName style") 
self.tap = nil 
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
self.tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) 
} 

required init?(coder aDecoder: NSCoder) { 
print("init coder style") 
self.tap = nil 
super.init(coder: aDecoder) 
tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) 
}} 
Các vấn đề liên quan