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))
        }
    }
}

尽管此时,您最好将交易信息和有效负载信息分离到单独的回调参数中。