【问题标题】:Is it possible to apply type erasure to returned value in protocol?是否可以将类型擦除应用于协议中的返回值?
【发布时间】:2018-06-09 06:44:13
【问题描述】:

好的,现在标题可能有点含糊,但基本上,我想要实现的是以下内容: 假设我有两个类用于从后端获取数据,它们都缓存获取的数据,因此,它们都有一个 invalidateCache() 方法。由于它们用于获取数据,因此它们中的每一个都有一个方法fetch(),它返回不同类型的对象:

class UserManager {
    ...
    func invalidateCache() {
        ...
    }
    func fetch() -> [User] {
        ...
        return users
    }
}

class PostManager {
    ...
    func invalidateCache() {
        ...
    }
    func fetch() -> [Post] {
        ...
        return posts
    }
}

然后我有一个基本视图控制器和两个继承的视图控制器(例如,UsersViewControllerPostsViewController),它们是我实际使用的。这两个视图控制器使用相应的实体管理器。我想要一些通用协议,它将是基本视图控制器中的一种属性类型,并且每个继承的协议都有特定的实现,如下所示:

protocol EntityManager<Result>: class {
    func invalidateCache()
    func fetch() -> [Result]
}

class UserManager: EntityManager<User> {
    ...
    func fetch() -> [User] {
        ...
    }
}

class PostManager: EntityManager<Post> {
    ...
    func fetch() -> [Post] {
        ...
    }
}


class BaseViewController: UIViewController {
    var manager: EntityManager?
    override func viewDidDisappear() {
        manager?.invalidateCache()
    }
}

class UserViewController: BaseViewController {
    var users: [User]?
    override func viewDidLoad() {
        super.viewDidLoad()
        manager = UserManager()
        users = manager?.fetch()
    }
}

class PostViewController: BaseViewController {
    var posts: [Post]?
    override func viewDidLoad() {
        super.viewDidLoad()
        manager = PostManager()
        posts = manager?.fetch()
    }
}

我尝试应用类型擦除,但没有以任何方式成功(我怀疑我并不完全了解类型擦除的应用领域)。据我了解,快速编译器要求类型在编译时必须是单义的,我只是不明白为什么我的情况有歧义。

【问题讨论】:

    标签: ios swift types compilation protocols


    【解决方案1】:

    您需要 User 和 Post 才能有共同点。例如,

    protocol Fetchable { }
    class User: Fetchable { }
    class Post: Fetchable { }
    
    class Manageable<T> {
        func fetch() -> [T] { return [] }
    }
    class UserManager: Manageable<User> {
        override func fetch() -> [User] { return [] }
    }
    class PostManager: Manageable<Post> {
        override func fetch() -> [Post] { return [] }
    }
    
    let users = UserManager().fetch()
    print("users=\(users)")
    let posts = PostManager().fetch()
    print("posts=\(posts)")
    

    【讨论】:

      猜你喜欢
      • 2012-06-19
      • 1970-01-01
      • 1970-01-01
      • 2020-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-22
      • 1970-01-01
      相关资源
      最近更新 更多