首页 文章

协议'BaseListPresenter'只能用作通用约束,因为它具有Self或关联类型要求

提问于
浏览
0

我正在定义一个具有某些功能和变量的协议

protocol BaseListPresenter {
    associatedtype T
    var values: [T] {get}
}

extension BaseListPresenter {

    public func count() -> Int {
        return values.count
    }

    public func valueAtIndex(index: Int) -> T? {
        return values[index]
    }
}

现在,我想在课堂上使用它:

class X: UIViewController {
    var listPresenter: BaseListPresenter? // HERE it gives me error

    // some other functions and variables here
}

上面说的错误:协议'BaseListPresenter'只能用作通用约束,因为它具有Self或相关类型要求

现在,我定义X的子类:

class Y: X {
    func setPresenter() {
        self.listPresenter = UsersPresenter() // UsersPresenter confirms BaseListPresenter protocol with value's type "User"
    }
    // many more functions below
}

class Z: X {
    func setPresenter() {
        self.listPresenter = RoomsPresenter() // RoomsPresenter confirms BaseListPresenter protocol with value's type "Room"
    }
     // many more functions below
}

我已经通过创建UsersPresenter和RoomsPresenter从(Protocol can only be used as a generic constraint because it has Self or associatedType requirements)获得了解决方案 . 但是,我想创建BaseListPresenter类型变量,它将在X中采用不同类型的值(UIViewController);一次房间和下一次用户取决于X的子类 .

我该如何解决这个问题并按我的意愿使用?

1 回答

  • 0

    问题是,当协议在某处使用时,必须确定协议的相关类型 . 在您的类 X 的实现中,编译器不知道 T 是什么类型 .

    我会这样实现它:

    class X<TPresenter : BaseListPresenter>: UIViewController {
        var listPresenter: TPresenter? // HERE it gives me error
    
        // some other functions and variables here
    }
    

    派生时,请专门 X

    class Y: X<UsersPresenter> {
        func setPresenter() {
            self.listPresenter = UsersPresenter() // UsersPresenter confirms BaseListPresenter protocol with value's type "User"
        }
        // many more functions below
    }
    
    class Z: X<RoomsPresenter> {
        func setPresenter() {
            self.listPresenter = RoomsPresenter() // RoomsPresenter confirms BaseListPresenter protocol with value's type "Room"
        }
         // many more functions below
    }
    

    这个结构有效 .

    注意:在UIViewController派生类中使用泛型使我在一年前遇到了一些麻烦 . Xcode /编译器无法将通用控制器与故事板中的场景链接起来 . 它不会导致编译错误,但它在运行时没有用 - 花费数小时的诊断时间 .

相关问题