Як зробити клас відповідним протоколу в Swift?


121

в Objective-C:

@interface CustomDataSource : NSObject <UITableViewDataSource>

@end

у Свіфті:

class CustomDataSource : UITableViewDataSource {

}

Однак з'явиться повідомлення про помилку:

  1. Тип "CellDatasDataSource" не відповідає протоколу "NSObjectProtocol"
  2. Тип "CellDatasDataSource" не відповідає протоколу "UITableViewDataSource"

Яким має бути правильний шлях?


1
Ім'я класу у ваших повідомленнях про помилку, схоже, не відповідає вашому наданому коду?
Метт Гібсон

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 Напевно ти мав на увазі недостатнє. "Не відповідає протоколу" для мене не означає "успадкувати від NSObject".
Рой Фолк

@RoyFalk Я маю на увазі попередження про компіляцію, яке було достатньо через помилку ... Можливо, вам не потрібно буде реалізовувати весь протокол у всіх випадках і, можливо, хочете створити його до цього ... це не велика справа, але відчуває себе трохи непотрібним .
Магуо

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 :

Показує попередження / підказку щодо застосування обов'язкових методів:

введіть тут опис зображення

Натисніть кнопку "Виправити", вона додасть усі обов'язкові методи в код:

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.