Comment rendre une classe conforme à un protocole dans Swift?

121

en Objective-C:

@interface CustomDataSource : NSObject <UITableViewDataSource>

@end

dans Swift:

class CustomDataSource : UITableViewDataSource {

}

Cependant, un message d'erreur apparaîtra:

  1. Le type 'CellDatasDataSource' n'est pas conforme au protocole 'NSObjectProtocol'
  2. Le type 'CellDatasDataSource' n'est pas conforme au protocole 'UITableViewDataSource'

Quelle devrait être la bonne manière?

YuXuan Fu
la source
1
Le nom de la classe dans vos messages d'erreur ne semble pas correspondre à votre code fourni?
Matt Gibson
2
Les classes Swift n'héritent pas par défaut de NSObject. Ce sont leurs propres classes de base, sauf indication contraire.
Tim

Réponses:

251

Le type 'CellDatasDataSource' n'est pas conforme au protocole 'NSObjectProtocol'

Vous devez faire hériter de votre classe NSObjectpour vous conformer à laNSObjectProtocol . Les classes Vanilla Swift ne le font pas. Mais de nombreuses parties de l' UIKitattente de l' NSObjectart.

class CustomDataSource : NSObject, UITableViewDataSource {

}

Mais ça:

Le type 'CellDatasDataSource' n'est pas conforme au protocole 'UITableViewDataSource'

Devrait. Vous obtiendrez l'erreur jusqu'à ce que votre classe implémente toutes les méthodes requises du protocole.

Alors, codez :)

Alex Wayne
la source
Merci @Alex; vous avez sauvé ma journée, car j'ai eu du mal à faire en sorte que ma classe Swift soit conforme au protocole UICollectionViewDataSource. L'ajout de l'héritage NSObject dans ma classe l'a résolu!
iOS-Coder
1
Suis-je le seul à penser qu'un avertissement de compilation était suffisant?
Magoo
@Magoo Vous vouliez sûrement dire insuffisant. «Ne se conforme pas au protocole» ne signifie pas pour moi «hériter de NSObject».
Roy Falk
@RoyFalk Je veux dire qu'un avertissement de compilation était suffisant en cas d'erreur ... Vous n'aurez peut-être pas besoin d'implémenter l'intégralité du protocole dans tous les cas et vous voudrez peut-être construire avant de le faire ... ce n'est pas un gros problème, mais vous vous sentez un peu inutile .
Magoo
0

Une classe doit hériter d'une classe parente avant de se conformer au protocole. Il existe principalement deux façons de procéder.

Une façon est que votre classe hérite NSObjectet se conforme à l' UITableViewDataSourceensemble. Maintenant, si vous souhaitez modifier les fonctions dans le protocole, vous devez ajouter un mot-clé overrideavant l'appel de la fonction, comme ceci

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

Cependant, cela rend parfois votre code confus car vous pouvez avoir de nombreux protocoles à respecter et chaque protocole peut avoir plusieurs fonctions de délégué. Dans cette situation, vous pouvez séparer le code conforme au protocole de la classe principale en utilisant extension, et vous n'avez pas besoin d'ajouter de overridemot-clé dans l'extension. Donc l'équivalent du code ci-dessus sera

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
    }
}
Fangming
la source
0

Xcode 9, aide à implémenter toutes les méthodes obligatoires de Swift Datasource & Delegates.

Voici un exemple de UITableViewDataSource :

Affiche un avertissement / un conseil pour implémenter les méthodes obligatoires:

entrez la description de l'image ici

Cliquez sur le bouton 'Fix', il ajoutera toutes les méthodes obligatoires dans le code:

entrez la description de l'image ici

Krunal
la source