Wie kann eine Klasse in Swift an ein Protokoll angepasst werden?

121

in Ziel-C:

@interface CustomDataSource : NSObject <UITableViewDataSource>

@end

in Swift:

class CustomDataSource : UITableViewDataSource {

}

Es wird jedoch eine Fehlermeldung angezeigt:

  1. Der Typ 'CellDatasDataSource' entspricht nicht dem Protokoll 'NSObjectProtocol'.
  2. Der Typ 'CellDatasDataSource' entspricht nicht dem Protokoll 'UITableViewDataSource'.

Was sollte der richtige Weg sein?

YuXuan Fu
quelle
1
Der Klassenname in Ihren Fehlermeldungen scheint nicht mit Ihrem angegebenen Code übereinzustimmen?
Matt Gibson
2
Swift-Klassen erben standardmäßig nicht von NSObject. Sie sind ihre eigenen Basisklassen, sofern nicht anders angegeben.
Tim

Antworten:

251

Der Typ 'CellDatasDataSource' entspricht nicht dem Protokoll 'NSObjectProtocol'.

Sie müssen Ihre Klasse erben lassen NSObject, um sich an die anzupassen NSObjectProtocol. Vanilla Swift Klassen nicht. Aber viele Teile UIKiterwarten NSObjects.

class CustomDataSource : NSObject, UITableViewDataSource {

}

Aber dieses:

Der Typ 'CellDatasDataSource' entspricht nicht dem Protokoll 'UITableViewDataSource'.

Wird erwartet. Sie erhalten den Fehler, bis Ihre Klasse alle erforderlichen Methoden des Protokolls implementiert.

Also Codierung bekommen :)

Alex Wayne
quelle
Danke @Alex; Sie haben meinen Tag gerettet, da ich schon seit einiger Zeit Probleme habe, meine Swift-Klasse an das UICollectionViewDataSource-Protokoll anzupassen. Das Hinzufügen der NSObject-Vererbung in meiner Klasse hat das Problem gelöst!
iOS-Coder
1
Bin ich der einzige, der glaubt, dass eine Kompilierungswarnung ausreichend war?
Magoo
@ Magoo Sicher meintest du unzureichend. "Entspricht nicht dem Protokoll" bedeutet für mich nicht "von NSObject erben".
Roy Falk
@RoyFalk Ich meine, eine Kompilierungswarnung war wegen eines Fehlers ausreichend ... Möglicherweise müssen Sie nicht in allen Fällen das gesamte Protokoll implementieren und möchten es möglicherweise vorher erstellen ... es ist keine große Sache, fühlt sich aber etwas unnötig an .
Magoo
0

Eine Klasse muss von einer übergeordneten Klasse erben, bevor sie dem Protokoll entspricht. Es gibt hauptsächlich zwei Möglichkeiten, dies zu tun.

Eine Möglichkeit besteht darin, Ihre Klasse von NSObjectder UITableViewDataSourcegemeinsamen erben zu lassen und sich an diese anzupassen . Wenn Sie nun die Funktionen im Protokoll ändern möchten, müssen Sie overridevor dem Funktionsaufruf wie folgt ein Schlüsselwort hinzufügen

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

Dies führt jedoch manchmal dazu, dass Ihr Code unübersichtlich wird, da Sie möglicherweise viele Protokolle einhalten müssen und jedes Protokoll mehrere Delegatenfunktionen haben kann. In dieser Situation können Sie den protokollkonformen Code mithilfe von von der Hauptklasse trennen extension, und Sie müssen overrideder Erweiterung kein Schlüsselwort hinzufügen . Das Äquivalent des obigen Codes ist also

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
quelle
0

Xcode 9 hilft bei der Implementierung aller obligatorischen Methoden von Swift Datasource & Delegates.

Hier ist ein Beispiel für UITableViewDataSource:

Zeigt Warnung / Hinweis zum Implementieren obligatorischer Methoden an:

Geben Sie hier die Bildbeschreibung ein

Klicken Sie auf die Schaltfläche 'Fix', um alle obligatorischen Methoden im Code hinzuzufügen:

Geben Sie hier die Bildbeschreibung ein

Krunal
quelle