Lớp không có trình khởi tạo Swift


181

Tôi có một vấn đề với lớp Swift. Tôi có một tệp swift cho lớp UITableViewControll và lớp UITableViewCell. Vấn đề của tôi là lớp UITableViewCell và các cửa hàng. Lớp này có lỗi Lớp "HomeCell" không có bộ khởi tạo và tôi không hiểu vấn đề này.

Cảm ơn câu trả lời của bạn.

import Foundation
import UIKit

class HomeTable: UITableViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet var tableViex: UITableView!

    var items: [(String, String, String)] = [
        ("Test", "123", "1.jpeg"),
        ("Test2", "236", "2.jpeg"),
        ("Test3", "678", "3.jpeg")
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        var nib = UINib(nibName: "HomeCell", bundle: nil)
        tableView.registerNib(nib, forCellReuseIdentifier: "bookCell")
    }

    // Number row
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.items.count
    }

    // Style Cell
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("bookCell") as UITableViewCell

        // Style here

        return cell

    }

    // Select row
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // Select
    }

}

// PROBLEM HERE
class HomeCell : UITableViewCell {

    @IBOutlet var imgBook: UIImageView
    @IBOutlet var titleBook: UILabel
    @IBOutlet var pageBook: UILabel

    func loadItem(#title: String, page: String, image:String) {
        titleBook.text = title
        pageBook.text = page
        imgBook.image = UIImage(named: image)
    }

}

Bạn có cần nêu rõ loại biến nib là một UINib tùy chọn không?
Cocoadelica

Câu trả lời:


257

Bạn phải sử dụng các tùy chọn không được bao bọc hoàn toàn để Swift có thể đối phó với các phụ thuộc vòng tròn (cha mẹ <-> con của các thành phần UI trong trường hợp này) trong giai đoạn khởi tạo.

@IBOutlet var imgBook: UIImageView!
@IBOutlet var titleBook: UILabel!
@IBOutlet var pageBook: UILabel!

Đọc tài liệu này , họ giải thích tất cả độc đáo.


21
Lời giải thích của bạn, và tài liệu đó, tất cả đều có ý nghĩa với tôi, nhưng không phải là thông báo lỗi!
coco

4
Đó có lẽ là một câu hỏi cho Apple
mprivat

Ngoài ra @IBOutlets nên được đánh dấu là yếu để tránh chu kỳ giữ lại.
Dennis Pashkov

@Dennis Pashkov Theo như tôi biết, nó chỉ dành cho IBOutlets nằm trong hệ thống phân cấp khung nhìn của viewContoder. Nếu không nó sẽ được phát hành ngay lập tức vì không ai giữ nó.
Alston

3
Tôi đã có vấn đề này khi tôi xác định Bool bằng cách sử dụng var myBool: Bool.
jungledev

96

Khắc phục nhanh - đảm bảo tất cả các biến không được khởi tạo khi chúng được tạo (ví dụ var num : Int?vs var num = 5) có a ?hoặc !.

Câu trả lời dài (giới thiệu) - đọc tài liệu theo mprivat gợi ý ...


Để khắc phục lỗi này bạn cần thiết lập giá trị mặc định cho? các biến, ví dụ: let showUserPointViewDelegate: ShowUserPointsViewControllControl? = nil
Vladimir Vodolazkiy 18/03/2016

+1 ?có nghĩa là có thể không, nhưng nếu đó không có vấn đề gì với việc tiến lên và không làm gì cả. !có nghĩa là nếu sau khi mở khóa nó là con số không, thì sự cố cả hai đều thỏa mãn yêu cầu khởi tạo. Bạn nên thông báo cho trình biên dịch: Tôi biết / muốn rằng nó sẽ bắt đầu từ con số không.
Mật ong

Tìm kiếm varlettrong bạn xem bộ điều khiển, và nhìn cho thiếu !s và ?s
Wiingaard

33

Đây là từ tài liệu của Apple

Các lớp và cấu trúc phải đặt tất cả các thuộc tính được lưu trữ của chúng thành một giá trị ban đầu thích hợp vào thời điểm một thể hiện của lớp hoặc cấu trúc đó được tạo. Các thuộc tính được lưu trữ không thể để ở trạng thái không xác định.

Bạn nhận được thông báo lỗi Lớp "HomeCell" không có bộ khởi tạo vì các biến của bạn ở trạng thái không xác định. Hoặc bạn tạo các trình khởi tạo hoặc bạn tạo cho chúng các loại tùy chọn, sử dụng! hoặc là ?


32

Câu trả lời của tôi giải quyết lỗi nói chung và không phải là mã chính xác của OP. Không có câu trả lời đề cập đến ghi chú này vì vậy tôi chỉ nghĩ rằng tôi thêm nó.

Mã dưới đây cũng sẽ tạo ra lỗi tương tự :

class Actor {
    let agent : String? // BAD! // Its value is set to nil, and will always be nil and that's stupid so Xcode is saying not-accepted.  
    // Technically speaking you have a way around it🤓, you can help the compiler and enforce your value as a constant. See Option3
}

Những người khác đề cập rằng Hoặc bạn tạo trình khởi tạo hoặc bạn tạo cho họ các loại tùy chọn, sử dụng! hoặc là ? cái nào đúng Tuy nhiên, nếu bạn có một thành viên / tài sản tùy chọn, tùy chọn đó sẽ có thể thay đổi tức là var. Nếu bạn thực hiện letthì nó sẽ không bao giờ có thể thoát khỏi niltrạng thái của nó . Điều đó thật xấu!

Vì vậy, cách viết chính xác là:

Lựa chọn 1

class Actor {
    var agent : String? // It's defaulted to `nil`, but also has a chance so it later can be set to something different || GOOD!
}

Hoặc bạn có thể viết nó dưới dạng:

Lựa chọn 2

class Actor {
let agent : String? // It's value isn't set to nil, but has an initializer || GOOD!

init (agent: String?){
    self.agent = agent // it has a chance so its value can be set!
    }
}

hoặc mặc định nó thành bất kỳ giá trị nào (bao gồm cả nilđiều đó hơi ngu ngốc)

Tùy chọn3

class Actor {
let agent : String? = nil // very useless, but doable.
let company: String? = "Universal" 
}

Nếu bạn tò mò về lý do tại sao let(trái với var) không được khởi tạo nilthì hãy đọc ở đâyđây


2
Cảm ơn bạn đã thêm điều này vì nó là một phần quan trọng của hình ảnh.
Jim

Giải thích tốt !!
Mahendra

1
Cài đặt thành không phải là ngu ngốc, nhưng vốn có bao nhiêu mô hình hoạt động.
đã vẽ ..

@drew .. thiết lập một cái gì đó bất biến nillà rất sai. Thiết lập một varđể nillà một điều khác nhau.
Mật ong

Này Honey, người đang nói chuyện với những đồ vật bất biến?
đã vẽ ..

10

Trong trường hợp của tôi, tôi đã tuyên bố Boolnhư thế này:

var isActivityOpen: Bool 

tức là tôi đã khai báo mà không hủy bỏ, vì vậy đây là cách tôi giải quyết lỗi ( không có trình khởi tạo ):

var isActivityOpen: Bool!

1

Không phải là một câu trả lời cụ thể cho câu hỏi của bạn nhưng tôi đã gặp lỗi này khi tôi không đặt giá trị ban đầu cho một enum trong khi khai báo nó là một tài sản. Tôi đã gán một giá trị ban đầu cho enum để giải quyết lỗi này. Đăng ở đây vì nó có thể giúp một ai đó.


0

chỉ cần cung cấp khối init cho lớp HomeCell

nó hoạt động trong trường hợp của tôi

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.