是否可以将类型擦除应用于协议中的返回值?

时间:2017-12-28 18:02:04

标签: ios swift types compilation protocols

现在好了,标题可能有点含糊不清,但基本上,我想要实现的目标如下: 假设我有两个用于从后端获取数据的类,它们都缓存获取的数据,因此,它们都有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()
    }
}

我尝试应用类型擦除但在任何方面都没有成功(我怀疑我不完全理解类型擦除的应用范围)。据我了解,swift编译器要求在编译期间类型必须是单义的,我只是不理解为什么在我的情况下存在歧义。

1 个答案:

答案 0 :(得分:0)

你需要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)")