จะทำให้คลาสเป็นไปตามโปรโตคอลใน Swift ได้อย่างไร


121

ใน Objective-C:

@interface CustomDataSource : NSObject <UITableViewDataSource>

@end

ใน Swift:

class CustomDataSource : UITableViewDataSource {

}

อย่างไรก็ตามข้อความแสดงข้อผิดพลาดจะปรากฏขึ้น:

  1. ประเภท 'CellDatasDataSource' ไม่สอดคล้องกับโปรโตคอล 'NSObjectProtocol'
  2. ประเภท 'CellDatasDataSource' ไม่สอดคล้องกับโปรโตคอล 'UITableViewDataSource'

วิธีที่ถูกต้องควรเป็นอย่างไร?


1
ชื่อคลาสในข้อความแสดงข้อผิดพลาดของคุณดูเหมือนจะไม่ตรงกับรหัสที่คุณให้มา?
Matt Gibson

2
คลาส Swift ไม่ได้รับมรดกจาก NSObject ตามค่าเริ่มต้น เป็นคลาสพื้นฐานของตนเองเว้นแต่จะระบุไว้เป็นอย่างอื่น
ทิม

คำตอบ:


251

ประเภท 'CellDatasDataSource' ไม่สอดคล้องกับโปรโตคอล 'NSObjectProtocol'

คุณต้องทำให้คลาสของคุณสืบทอดจากNSObjectเพื่อให้สอดคล้องกับNSObjectProtocol. คลาส Vanilla Swift ทำไม่ได้ แต่หลายส่วนของความUIKitคาดหวังNSObjects.

class CustomDataSource : NSObject, UITableViewDataSource {

}

แต่นี่:

ประเภท 'CellDatasDataSource' ไม่สอดคล้องกับโปรโตคอล 'UITableViewDataSource'

คาดว่า. คุณจะได้รับข้อผิดพลาดจนกว่าชั้นเรียนของคุณจะใช้วิธีการที่จำเป็นทั้งหมดของโปรโตคอล

ดังนั้นรับการเข้ารหัส :)


ขอบคุณ @Alex; คุณช่วยวันของฉันไว้เนื่องจากฉันพยายามอยู่พอสมควรเพื่อให้คลาส Swift ของฉันเป็นไปตามโปรโตคอล UICollectionViewDataSource การเพิ่มการสืบทอดวัตถุ NSObject ในชั้นเรียนของฉันแก้ไขได้!
iOS-Coder

1
ฉันเป็นคนเดียวที่คิดว่าคำเตือนการรวบรวมเพียงพอหรือไม่?
Magoo

@ Magoo แน่นอนคุณหมายถึงไม่เพียงพอ 'ไม่เป็นไปตามโปรโตคอล' ไม่ได้หมายความว่า 'สืบทอดจาก NSObject' มาให้ฉัน
Roy Falk

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

0

คลาสต้องสืบทอดจากคลาสพาเรนต์ก่อนที่จะเป็นไปตามโปรโตคอล ส่วนใหญ่มีสองวิธีในการทำ

วิธีหนึ่งคือให้คลาสของคุณสืบทอดNSObjectและสอดคล้องกับคลาสUITableViewDataSourceด้วยกัน ตอนนี้หากคุณต้องการแก้ไขฟังก์ชันในโปรโตคอลคุณต้องเพิ่มคำสำคัญoverrideก่อนการเรียกใช้ฟังก์ชันเช่นนี้

class CustomDataSource : NSObject, UITableViewDataSource {

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

        // Configure the cell...

        return cell
    }
}

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

class CustomDataSource : NSObject{
    // Configure the object...
}

extension CustomDataSource: UITableViewDataSource {

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

        // Configure the cell...

        return cell
    }
}

0

Xcode 9 ช่วยในการใช้วิธีการบังคับทั้งหมดของ Swift Datasource & Delegates

นี่คือตัวอย่างของUITableViewDataSource:

แสดงคำเตือน / คำแนะนำในการใช้วิธีการบังคับ:

ใส่คำอธิบายภาพที่นี่

คลิกที่ปุ่ม 'แก้ไข' มันจะเพิ่มวิธีการบังคับทั้งหมดในโค้ด:

ใส่คำอธิบายภาพที่นี่

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