Ios 均衡实现不需要';我似乎无法使用泛型
我仍在与迅捷的仿制药抗争。今天我发现我的Equatable协议的实现不起作用,如果它是从泛型类调用的 我的模型课:Ios 均衡实现不需要';我似乎无法使用泛型,ios,generics,swift,Ios,Generics,Swift,我仍在与迅捷的仿制药抗争。今天我发现我的Equatable协议的实现不起作用,如果它是从泛型类调用的 我的模型课: func ==(lhs: Tracking, rhs: Tracking) -> Bool { // This method never executes if called from BaseCache return lhs.id == rhs.id } class Tracking: NSObject, Equatable, Printable {
func ==(lhs: Tracking, rhs: Tracking) -> Bool {
// This method never executes if called from BaseCache
return lhs.id == rhs.id
}
class Tracking: NSObject, Equatable, Printable {
var id: String?
.....
}
类,它使用泛型类型:
class BaseCache<T: NSObject where T: Equatable, T: Printable> {
.....
func removeEntities(entities: [T]) {
var indexesToRemove = [Int]()
for i in 0...allEntities.count - 1 {
let item = allEntities[i]
for entity in entities {
println("equal: \(entity == item)")
// FOR SOME REASONS THE STATEMENT BELOW IS ALWAYS FALSE
if entity == item {
indexesToRemove.append(i)
break
}
}
}
for index in indexesToRemove {
allEntities.removeAtIndex(index)
}
didRemoveEntities()
}
}
类基本缓存{
.....
功能删除实体(实体:[T]){
var indexesToRemove=[Int]()
对于0…allenties.count-1中的i{
let item=allenties[i]
对于实体中的实体{
println(“相等:\(实体==项目)”)
//由于某些原因,下面的陈述总是错误的
如果实体==项目{
indexesToRemove.append(i)
打破
}
}
}
对于IndexStoreMove中的索引{
Allenties.removeAtIndex(索引)
}
didremoventies()
}
}
它是一个子类:
class TrackingCache<T: Tracking>: BaseCache<Tracking> {
}
class TrackingCache:BaseCache{
}
当我调用TrackingCache
实例的removeenties
方法时,我总是在输出中得到equal:false
,即使id
s是相同的
但是如果我直接将该方法移动到TrackingCache
类,它似乎工作得很好
知道为什么会发生这种情况以及如何解决吗?注意:由于
=
不是成员函数,因此默认情况下它不会为您提供动态调度,包括在通用占位符旁边使用时
考虑以下代码:
class C: NSObject, Equatable {
let id: Int
init(_ id: Int) { self.id = id }
}
// define equality as IDs are equal
func ==(lhs: C, rhs: C) -> Bool {
return lhs.id == rhs.id
}
// create two objects with the same ID
let c1 = C(1)
let c2 = C(1)
// true, as expected
c1 == c2
确定现在创建两个类型为NSObject
的变量,并将相同的值分配给它们:
let o1: NSObject = c1
let o2: NSObject = c2
// this will be false
o1 == o2
为什么??因为您正在调用函数func==(lhs:NSObject,rhs:NSObject)->Bool
,而不是func==(lhs:C,rhs:C)->Bool
。选择哪个重载函数在运行时不会根据o1
和o2
所指内容动态确定。它是由Swift在编译时根据o1
和o2
的类型确定的,在这种情况下是NSObject
NSObject
=
的实现方式与您的equals不同–它调用lhs.isEqual(rhs)
,如果不重写,它会返回到检查引用相等性(即两个引用指向同一个对象)。他们不是,所以他们不平等
为什么使用BaseCache
时会发生这种情况,而使用TrackingCache
时不会发生这种情况?由于BaseCache
被定义为仅约束NSObject
,因此T
仅具有NSObject
的功能–类似于将c1
分配给NSObject
类型的变量时,将调用NSObject
版本的=/code>
另一方面,TrackingCache
保证T
将至少是一个跟踪
对象,因此使用用于跟踪的=
版本。Swift将在所有可能的重载中选择更“具体的”–跟踪
比它的基类NSObject
更具体
下面是一个简单的示例,仅针对泛型函数:
func f<T: NSObject>(lhs: T, rhs: T) -> Bool {
return lhs == rhs
}
func g<T: C>(lhs: T, rhs: T) -> Bool {
return lhs == rhs
}
f(c1, c2) // false
g(c1, c2) // true
这种技术(让==
调用动态调度的类方法)也是为非NSObject类实现这种行为的一种方法。当然,结构没有这个问题,因为它们不支持继承——结构得1分 顺便说一句,您可以为0中的i编写,而不是…allenties.count-1
您可以为0中的i编写。根据allenties
是什么,您也可以为allenties
中的项指定。不过,他需要一个索引,以便稍后进行删除
中的(idx,item)代码>会起作用-它依赖于Int
索引,但这里就是这种情况。@空速性能感谢您的建议,但它似乎包含使用均衡实现,这不会起作用,对吗?@AndreyGordeev根据我的回答,如果您实现equalable以使用isEqual
class C: NSObject, Equatable {
...
override func isEqual(object: AnyObject?) -> Bool {
return (object as? C)?.id == id
}
}
// this is now true:
o1 == o2
// as is this:
f(c1, c2)