Swift - 动态转换 class 无条件?
Swift - Dynamic cast class unconditional?
我似乎不能将泛型转换为另一个泛型? Swift 正在抛出 DynamicCastClassException。
问题基本上是这样的:
// T is defined as T: NSObject
let oebj1 = NetworkResponse<User>()
let oebj2 = oebj1 as NetworkResponse<NSObject>
这就是为什么我需要做这个转换
class BaseViewController: UIViewController {
// Not allowed to make a generic viewController and therefore have to cast the generic down to NSObject
func fetchData(completion: (NetworkResponse<NSObject>)->()) {
fatalError("You have to implement fetchData method")
}
}
class UsersViewController: BaseViewController {
override func fetchData(completion: (NetworkResponse<NSObject>)->()) {
userNetworkManager.fetchUsers { networkUSerResponse in
completion(networkUSerResponse as NetworkResponse<NSObject>)
}
}
}
class UserNetworkManager {
func fetchUsers(completion: (NetworkResponse<User>)->()) {
// Do stuff
}
}
总的来说,似乎没有办法做到这一点。基本问题是 NetworkResponse<NSObject>
和 NetworkResponse<User>
本质上是完全不相关的类型,它们恰好具有相同的功能和相似的命名。
在这种特定情况下,它确实没有必要,因为无论如何您都在丢弃已知的 User
结果,这意味着如果您真的想将其视为 User
稍后你将不得不进行有条件的回退。只需从 NetworkResponse
中删除泛型,它就会按预期工作。主要缺点是在 UserVC.fetchData
内,如果没有(条件)转换,您将无法访问返回的 User
结果。
另一种解决方案是使用某种包装器(假设有重要的那里的边带数据)。这样你就可以将 NetworkResponse
传递给 super 而不会被破坏,并根据需要向下转换有效负载对象。
像这样:
class User : NSObject {
}
class Transaction {
let request:NSURLRequest?
let response:NSURLResponse?
let data:NSData?
}
class Response<T:NSObject> {
let transaction:Transaction
let payload:T
init(transaction:Transaction, payload:T) {
self.transaction = transaction
self.payload = payload
}
}
class UserNetworkManager {
func fetchUsers(completion: (Response<User>) -> ()) {
completion(Response(transaction:Transaction(), payload:User()))
}
}
let userNetworkManager = UserNetworkManager();
class BaseVC {
func fetchData(completion: (Response<NSObject>) -> ()) {
fatalError("Gotta implement fetchData")
}
}
class UserVC : BaseVC {
override func fetchData(completion: (Response<NSObject>) -> ()) {
userNetworkManager.fetchUsers { response -> () in
completion(Response(transaction: response.transaction, payload: response.payload))
}
}
}
尽管此时,您最好将交易信息和有效负载信息分离到单独的回调参数中。
我似乎不能将泛型转换为另一个泛型? Swift 正在抛出 DynamicCastClassException。
问题基本上是这样的:
// T is defined as T: NSObject
let oebj1 = NetworkResponse<User>()
let oebj2 = oebj1 as NetworkResponse<NSObject>
这就是为什么我需要做这个转换
class BaseViewController: UIViewController {
// Not allowed to make a generic viewController and therefore have to cast the generic down to NSObject
func fetchData(completion: (NetworkResponse<NSObject>)->()) {
fatalError("You have to implement fetchData method")
}
}
class UsersViewController: BaseViewController {
override func fetchData(completion: (NetworkResponse<NSObject>)->()) {
userNetworkManager.fetchUsers { networkUSerResponse in
completion(networkUSerResponse as NetworkResponse<NSObject>)
}
}
}
class UserNetworkManager {
func fetchUsers(completion: (NetworkResponse<User>)->()) {
// Do stuff
}
}
总的来说,似乎没有办法做到这一点。基本问题是 NetworkResponse<NSObject>
和 NetworkResponse<User>
本质上是完全不相关的类型,它们恰好具有相同的功能和相似的命名。
在这种特定情况下,它确实没有必要,因为无论如何您都在丢弃已知的 User
结果,这意味着如果您真的想将其视为 User
稍后你将不得不进行有条件的回退。只需从 NetworkResponse
中删除泛型,它就会按预期工作。主要缺点是在 UserVC.fetchData
内,如果没有(条件)转换,您将无法访问返回的 User
结果。
另一种解决方案是使用某种包装器(假设有重要的那里的边带数据)。这样你就可以将 NetworkResponse
传递给 super 而不会被破坏,并根据需要向下转换有效负载对象。
像这样:
class User : NSObject {
}
class Transaction {
let request:NSURLRequest?
let response:NSURLResponse?
let data:NSData?
}
class Response<T:NSObject> {
let transaction:Transaction
let payload:T
init(transaction:Transaction, payload:T) {
self.transaction = transaction
self.payload = payload
}
}
class UserNetworkManager {
func fetchUsers(completion: (Response<User>) -> ()) {
completion(Response(transaction:Transaction(), payload:User()))
}
}
let userNetworkManager = UserNetworkManager();
class BaseVC {
func fetchData(completion: (Response<NSObject>) -> ()) {
fatalError("Gotta implement fetchData")
}
}
class UserVC : BaseVC {
override func fetchData(completion: (Response<NSObject>) -> ()) {
userNetworkManager.fetchUsers { response -> () in
completion(Response(transaction: response.transaction, payload: response.payload))
}
}
}
尽管此时,您最好将交易信息和有效负载信息分离到单独的回调参数中。