Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Swift Generics и расширения протокола

Автор вопроса: naglerrrОтветов: 2

У меня есть протокол Reusable, который имеет статическую функцию static func reuseId() -> String и расширение протокола, определяющее реализацию функции по умолчанию. Затем я реализовал расширение для UITableViewCell, чтобы оно соответствовало протоколу Reusable. Теперь я могу без проблем использовать эту функцию в своих TableViewCells: SomeTableViewCell.reuseId().

У меня проблема с дженериками. У меня есть универсальный класс с общим параметром типа UITableViewCell:

internal class SomeClass<CellType: UITableViewCell>: NSObject {
    ...
}

Я хочу иметь возможность использовать функцию, указанную в Reusable, в моем универсальном классе на CellType, но, к сожалению, это не работает должным образом. Компилятор всегда выдает ошибку Type 'CellType' has no member 'reuseId'.

Кто-нибудь знает, почему это происходит? Есть ли обходной путь?

Я использую Xcode 7.0 со Swift 2.0.

Привет из Германии

ОБНОВЛЕНИЕ: вот пример кода, который лучше показывает мою проблему:

import UIKit

protocol Reusable {
    static func reuseId() -> String
}

extension Reusable {
    static func reuseId() -> String {
        return String(self).componentsSeparatedByString(".").last!
    }
}

extension UITableViewCell: Reusable { }

class SomeGenericClass<CellType: UITableViewCell> {
    func someFunction() {
        let reuseIdentifier = CellType.reuseId()
    }
}

Этот код будет генерировать указанную выше ошибку, но я не совсем понимаю, почему это происходит. Я думаю, что основное отличие от примера кода, опубликованного jtbandes, заключается в том, что я использую статическую функцию.


ОБНОВЛЕНИЕ: проблема устранена в Xcode 8.3 beta 2. Приведенный выше пример кода теперь работает должным образом (конечно, после его переноса на Swift 3).

  • Было бы полезнее, если бы вы разместили (минимальный) пример фактического кода, а не только описывали проблему. Martin R 20.09.2015
  • Я добавил пример кода к своему исходному вопросу, который, надеюсь, сделает мой вопрос более понятным. naglerrr 20.09.2015

swiftgenericsprotocolsswift2xcode7

Ответы

Ответ 1 · jtbandes

Это интересная проблема. Похоже, ваш код должен работать; вы можете отправить запрос на улучшение.

Вот обходной путь, который работает правильно:

class SomeGenericClass<CellType: Cell> {
    func someFunction() {
        let reuseIdentifier = (CellType.self as Reusable.Type).reuseId()
    }
}

Ответ 2 · Benzi

Другой (обходной) способ получить то, что вам нужно:

class GenericExample<CellType:UITableViewCell where CellType:Reusable>
{
    func test() -> String {
        return CellType.reuseId()
    }
}

GenericExample<UITableViewCell>().test() // returns "UITableViewCell"
GenericExample<MyCell>().test() // returns "MyCell"

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы