这个问题CKRecord
询问是否可以在 Swift中使用下标。虽然我已经知道如何做提问者想要的,但它的每一个排列都会给我一个堆栈溢出:
subscript(key: String) -> CKRecordValue? {
get {
return objectForKey(key) as CKRecordValue?
}
set {
setObject(newValue, forKey: key)
}
}
堆栈溢出发生在 getter 中。(我从未尝试过 setter,所以它也可能在那里发生。)我尝试使用objectForKey:
、objectForKeyedSubscript:
和valueForKey:
. 都产生相同的结果:堆栈溢出。
这很奇怪,因为CKRecord
肯定是用 Objective-C 编写的。为什么会递归调用 Swift 的subscript
方法?这没有道理。Nate Cook 在回答提问者时想知道为什么 Swift 不会objectForKeyedSubscript:
自动桥接。好吧,也许执行此操作的代码没有完全烘焙,但导致了这个问题。我将不得不与另一个具有objectForKeyedSubscript:
.
更新
看起来objectForKeyedSubscript:
通常是桥接的。我使用适当的方法在 Objective-C 中创建了一个类,将其添加到桥接头中,索引器就在那里并且没有问题地编译。更好的是,它在没有堆栈溢出的情况下工作。
这意味着正在发生一些非常不寻常的事情CKRecord
。
理论
如果您在 Swift 中创建一个类,该类从a 作为键继承NSObject
并在其上实现该subscript
方法,则它String
变为objectForKeyedSubscript:
. (对于“纯 Swift”类,我怀疑情况并非如此。)您可以通过将 Swift 类导入到 Objective-C 并验证它objectForKeyedSubscript:
是否存在来验证这一点。
由于CKRecord
继承自NSObject
,因此实现subscript
会覆盖默认实现。objectForKey:
此外,似乎valueForKey:
所有最终都调用objectForKeyedSubscript:
了 ,这导致(阅读:“与”相同)调用subscript
,从而导致堆栈溢出。
这可以解释为什么会发生堆栈溢出。它仍然没有解释为什么objectForKeyedSubscript:
没有自动桥接,但也许是因为 的定义setObject:forKeyedSubscript:
与规范的类型签名略有不同:- (void)setObject:(id <CKRecordValue>)object forKeyedSubscript:(NSString *)key;
. 这对 Objective-C 没有影响,但可能会导致“桥接代码”出错。毕竟,Swift 是相当新的。