Làm thế nào để tạo một lớp phù hợp với một giao thức trong Swift?


121

trong Objective-C:

@interface CustomDataSource : NSObject <UITableViewDataSource>

@end

trong Swift:

class CustomDataSource : UITableViewDataSource {

}

Tuy nhiên, một thông báo lỗi sẽ xuất hiện:

  1. Loại 'CellDatasDataSource' không phù hợp với giao thức 'NSObjectProtocol'
  2. Loại 'CellDatasDataSource' không phù hợp với giao thức 'UITableViewDataSource'

Điều gì phải là cách chính xác?


1
Tên lớp trong thông báo lỗi của bạn dường như không khớp với mã bạn đã cung cấp?
Matt Gibson

2
Các lớp Swift theo mặc định không kế thừa từ NSObject. Chúng là các lớp cơ sở của riêng chúng trừ khi được chỉ định khác.
Tim

Câu trả lời:


251

Loại 'CellDatasDataSource' không phù hợp với giao thức 'NSObjectProtocol'

Bạn phải làm cho lớp của bạn kế thừa từ NSObjectđể phù hợp với NSObjectProtocol. Các lớp Vanilla Swift thì không. Nhưng nhiều phần UIKitmong đợi NSObjects.

class CustomDataSource : NSObject, UITableViewDataSource {

}

Nhưng điều này:

Loại 'CellDatasDataSource' không phù hợp với giao thức 'UITableViewDataSource'

Được mong đợi. Bạn sẽ gặp lỗi cho đến khi lớp của bạn triển khai tất cả các phương thức bắt buộc của giao thức.

Vì vậy, hãy mã hóa :)


Cảm ơn @Alex; bạn đã cứu được ngày của tôi, vì tôi đã khá vất vả để làm cho lớp Swift của mình tuân theo giao thức UICollectionViewDataSource. Việc thêm kế thừa NSObject trong Lớp của tôi đã giải quyết được vấn đề đó!
iOS-Coder

1
Tôi có phải là người duy nhất nghĩ rằng một cảnh báo biên dịch là đủ?
Magoo

@Magoo Chắc chắn bạn có nghĩa là không đủ. "Không tuân theo giao thức" không có nghĩa là "kế thừa từ NSObject" đối với tôi.
Roy Falk

@RoyFalk Ý tôi là một cảnh báo biên dịch là đủ khi có lỗi ... Bạn có thể không cần triển khai toàn bộ giao thức trong mọi trường hợp và có thể muốn xây dựng trước khi làm như vậy ... nó không phải là vấn đề lớn, nhưng cảm thấy hơi không cần thiết .
Magoo,

0

Một lớp phải kế thừa từ một lớp cha trước khi tuân theo giao thức. Chủ yếu có hai cách để làm điều đó.

Một cách là để lớp của bạn kế thừa NSObjectvà phù hợp với UITableViewDataSourcenhau. Bây giờ nếu bạn muốn sửa đổi các chức năng trong giao thức, bạn cần thêm từ khóa overridetrước khi gọi hàm, như thế này

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

Tuy nhiên, điều này đôi khi làm cho mã của bạn lộn xộn vì bạn có thể có nhiều giao thức để tuân theo và mỗi giao thức có thể có một số chức năng ủy quyền. Trong trường hợp này, bạn có thể tách mã tuân thủ giao thức ra khỏi lớp chính bằng cách sử dụng extensionvà bạn không cần thêm overridetừ khóa vào tiện ích mở rộng. Vì vậy, tương đương với mã trên sẽ là

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, giúp triển khai tất cả các phương thức bắt buộc của Swift Datasource & Delegates.

Đây là ví dụ về UITableViewDataSource:

Hiển thị cảnh báo / gợi ý để triển khai các phương pháp bắt buộc:

nhập mô tả hình ảnh ở đây

Nhấp vào nút 'Khắc phục', nó sẽ thêm tất cả các phương thức bắt buộc vào mã:

nhập mô tả hình ảnh ở đây

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.