Jak sprawić, by klasa była zgodna z protokołem w Swift?

121

w celu C:

@interface CustomDataSource : NSObject <UITableViewDataSource>

@end

w Swift:

class CustomDataSource : UITableViewDataSource {

}

Jednak pojawi się komunikat o błędzie:

  1. Typ „CellDatasDataSource” nie jest zgodny z protokołem „NSObjectProtocol”
  2. Typ „CellDatasDataSource” nie jest zgodny z protokołem „UITableViewDataSource”

Jaki powinien być właściwy sposób?

YuXuan Fu
źródło
1
Nazwa klasy w Twoich komunikatach o błędach nie pasuje do podanego kodu?
Matt Gibson,
2
Klasy Swift domyślnie nie dziedziczą po NSObject. Są to własne klasy bazowe, chyba że określono inaczej.
Tim

Odpowiedzi:

251

Typ „CellDatasDataSource” nie jest zgodny z protokołem „NSObjectProtocol”

Musisz sprawić, aby Twoja klasa dziedziczyła z, NSObjectaby była zgodna z NSObjectProtocol. Klasy Vanilla Swift nie. Ale wiele części UIKitoczekiwań NSObject.

class CustomDataSource : NSObject, UITableViewDataSource {

}

Ale to:

Typ „CellDatasDataSource” nie jest zgodny z protokołem „UITableViewDataSource”

Jest oczekiwany. Błąd pojawi się, dopóki Twoja klasa nie zaimplementuje wszystkich wymaganych metod protokołu.

Więc zacznij kodować :)

Alex Wayne
źródło
Dzięki @Alex; uratowałeś mi dzień, ponieważ od jakiegoś czasu zmagałem się, aby moja klasa Swift była zgodna z protokołem UICollectionViewDataSource. Dodanie dziedziczenia NSObject w mojej klasie rozwiązało problem!
iOS-Coder
1
Czy jestem jedynym, który uważa, że ​​ostrzeżenie dotyczące kompilacji było wystarczające?
Magoo
@Magoo Z pewnością miałeś na myśli niewystarczające. „Nie jest zgodny z protokołem” nie oznacza dla mnie „dziedziczenia po NSObject”.
Roy Falk
@RoyFalk Mam na myśli, że ostrzeżenie kompilacji było wystarczające w przypadku błędu ... Możesz nie potrzebować implementować całego protokołu we wszystkich przypadkach i możesz chcieć zbudować przedtem ... to nie jest wielka sprawa, ale wydaje się trochę niepotrzebna .
Magoo
0

Klasa musi dziedziczyć po klasie nadrzędnej, zanim będzie zgodna z protokołem. Są na to głównie dwa sposoby.

Jednym ze sposobów jest posiadanie przez klasę dziedziczenia NSObjecti dostosowywania się do UITableViewDataSourcesiebie. Teraz, jeśli chcesz zmodyfikować funkcje w protokole, musisz dodać słowo kluczowe overrideprzed wywołaniem funkcji, tak jak to

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

Jednak czasami powoduje to bałagan w kodzie, ponieważ możesz mieć wiele protokołów do dostosowania, a każdy protokół może mieć kilka funkcji delegowanych. W tej sytuacji możesz oddzielić kod zgodny z protokołem od głównej klasy za pomocą extensioni nie musisz dodawać overridesłowa kluczowego w rozszerzeniu. Więc odpowiednikiem powyższego kodu będzie

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
źródło
0

Xcode 9 pomaga we wdrażaniu wszystkich obowiązkowych metod Swift Datasource & Delegates.

Oto przykład UITableViewDataSource:

Pokazuje ostrzeżenie / podpowiedź do wdrożenia obowiązkowych metod:

wprowadź opis obrazu tutaj

Kliknij przycisk `` Napraw '', doda wszystkie obowiązkowe metody w kodzie:

wprowadź opis obrazu tutaj

Krunal
źródło