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

问题描述 投票:1回答:1

好了,标题可能有点含糊不清,但基本上,我想要实现的目的如下:假设我有两个类用于从后端获取数据,它们都缓存了获取的数据,因此,他们都有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编译器要求在编译期间类型必须是单义的,我只是不明白为什么在我的情况下存在歧义。

ios swift types compilation protocols
1个回答
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)")
© www.soinside.com 2019 - 2024. All rights reserved.