Class ไม่มี initializers Swift


181

ฉันมีปัญหากับคลาส Swift ฉันมีไฟล์ swift สำหรับคลาส UITableViewController และคลาส UITableViewCell ปัญหาของฉันคือคลาส UITableViewCell และร้านค้า คลาสนี้มีข้อผิดพลาดClass "HomeCell" ไม่มี initializersและฉันไม่เข้าใจปัญหานี้

ขอบคุณสำหรับคำตอบของคุณ

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

}

คุณต้องการระบุชนิดของตัวแปร nib อย่างชัดเจนเป็น UINib เผื่อเลือกหรือไม่?
Cocoadelica

คำตอบ:


257

คุณต้องใช้ตัวเลือกที่ยังไม่ได้เปิดโดยปริยายดังนั้น Swift สามารถรับมือกับการพึ่งพาแบบวงกลม (parent <-> ลูกขององค์ประกอบ UI ในกรณีนี้) ในระหว่างขั้นตอนการเริ่มต้น

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

อ่านเอกสารนี้พวกเขาอธิบายทุกอย่างไว้อย่างดี


21
คำอธิบายของคุณและเอกสารนั้นมีเหตุผลสำหรับฉัน แต่ไม่ใช่ข้อความแสดงข้อผิดพลาด!
coco

4
นั่นอาจเป็นคำถามสำหรับ Apple
mprivat

นอกจากนี้ @IBOutlet ควรทำเครื่องหมายว่าอ่อนแอเพื่อหลีกเลี่ยงวงจร
Dennis Pashkov

@Dennis Pashkov เท่าที่ฉันรู้มันมีไว้สำหรับ IBOutlets ที่อยู่ในลำดับชั้นการดูของ viewController เท่านั้น มิฉะนั้นจะถูกปล่อยออกมาทันทีเพราะไม่มีใครอุ้มไว้
Alston

3
ฉันมีปัญหานี้ที่ผมกำหนด Bool var myBool: Boolใช้
jungledev

96

แก้ไขด่วน - ให้แน่ใจว่าตัวแปรทั้งหมดที่ไม่ได้รับการเริ่มต้นได้เมื่อพวกเขาถูกสร้างขึ้น (เช่นvar num : Int?VS var num = 5) มีทั้งหรือ?!

คำตอบยาว (แนะนำอีกครั้ง) - อ่านเอกสารตาม mprivat แนะนำ ...


ในการแก้ไขข้อผิดพลาดนี้คุณต้องตั้งค่าเริ่มต้นสำหรับ ตัวแปรตัวอย่างเช่น: ให้ showUserPointViewDelegate: ShowUserPointsViewControllerControl? = ไม่มี
Vladimir Vodolazkiy

+1 ?หมายถึงอาจเป็นศูนย์ แต่ถ้าเป็นเช่นนั้นจะไม่มีปัญหาในการก้าวไปข้างหน้าและไม่ทำอะไรเลย !หมายความว่าถ้าหลังจากแกะมันเป็นศูนย์แล้วขัดข้อง - ทั้งสองสิ่งนี้ตอบสนองความต้องการในการเริ่มต้น - โดยคุณแจ้งผู้แปล: ฉันรู้ / ต้องการว่ามันจะเริ่มจากศูนย์
ฮันนี่

ค้นหาvarและletในตัวคุณดูคอนโทรลเลอร์และมองหา!s และ?s
Wiingaard ที่

33

นี่คือจากเอกสารของ Apple

คลาสและโครงสร้างต้องตั้งค่าคุณสมบัติที่เก็บไว้ทั้งหมดเป็นค่าเริ่มต้นที่เหมาะสมตามเวลาที่อินสแตนซ์ของคลาสหรือโครงสร้างนั้นถูกสร้างขึ้น คุณสมบัติที่เก็บไว้ไม่สามารถอยู่ในสถานะไม่แน่นอน

คุณได้รับข้อความแสดงข้อผิดพลาดClass "HomeCell" ไม่มี initializersเนื่องจากตัวแปรของคุณอยู่ในสถานะไม่แน่นอน ไม่ว่าคุณจะสร้างตัวเริ่มต้นหรือทำให้เป็นประเภทตัวเลือกใช้! หรือ ?


32

คำตอบของฉันระบุข้อผิดพลาดโดยทั่วไปไม่ใช่รหัสที่แน่นอนของ OP ไม่มีคำตอบที่กล่าวถึงบันทึกย่อนี้ดังนั้นฉันจึงคิดว่าจะเพิ่ม

รหัสด้านล่างจะสร้างข้อผิดพลาดเดียวกัน :

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
}

คนอื่น ๆ กล่าวว่าไม่ว่าคุณจะสร้างตัวเริ่มต้นหรือคุณกำหนดประเภทเป็นตัวเลือกโดยใช้! หรือ ? ซึ่งถูกต้อง แต่ถ้าคุณมีสมาชิกตัวเลือก / varคุณสมบัติไม่จำเป็นที่ควรจะเป็นคือไม่แน่นอน หากคุณสร้างletมันขึ้นมามันจะไม่สามารถหลุดออกจากมันได้nilสถานะดังกล่าวได้ เลวร้าย!

ดังนั้นวิธีที่ถูกต้องในการเขียนคือ:

ตัวเลือกที่ 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!
}

หรือคุณสามารถเขียนมันเป็น:

Option2

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

หรือเริ่มต้นเป็นค่าใด ๆ (รวมถึงnilที่เป็นคนโง่)

Option3

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

หากคุณสงสัยว่าทำไมlet(ตรงกันข้ามvar) ไม่ได้เริ่มต้นให้nilอ่านที่นี่และที่นี่


2
ขอบคุณที่เพิ่มสิ่งนี้เนื่องจากเป็นส่วนสำคัญของภาพ
Jim

อธิบายได้ดี !!
Mahendra

1
การตั้งค่าเป็นศูนย์ไม่ได้โง่ แต่โดยธรรมชาติแล้วมีกี่รุ่นที่ใช้งานได้
วาด ..

@ ดึง .. การตั้งค่าบางอย่างที่ไม่เปลี่ยนรูปnilผิดไปมาก การตั้งค่าvarที่จะnilเป็นสิ่งที่แตกต่างกัน
ฮันนี่

เฮ้ฮันนี่ใครกำลังพูดกับวัตถุที่ไม่เปลี่ยนรูป?
วาด ..

10

ในกรณีของฉันฉันได้ประกาศแบบBoolนี้:

var isActivityOpen: Bool 

เช่นฉันประกาศโดยไม่ต้องคลายออกนี่คือวิธีที่ฉันแก้ไขข้อผิดพลาด( ไม่มีตัวเริ่มต้น ):

var isActivityOpen: Bool!

1

ไม่ใช่คำตอบที่เฉพาะเจาะจงสำหรับคำถามของคุณ แต่ฉันได้รับข้อผิดพลาดนี้เมื่อฉันไม่ได้ตั้งค่าเริ่มต้นสำหรับ enum ในขณะที่ประกาศเป็นคุณสมบัติ ฉันกำหนดค่าเริ่มต้นให้กับ enum เพื่อแก้ไขข้อผิดพลาดนี้ การโพสต์ที่นี่เนื่องจากอาจช่วยคนได้


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.