gpt4 book ai didi

swift - 在 Swift 中的 CKRecord 上定义下标时发生堆栈溢出

转载 作者:搜寻专家 更新时间:2023-10-30 22:14:25 25 4
gpt4 key购买 nike

This question询问是否可以使用 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 中创建一个继承自 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 很新。

最佳答案

经过一些测试和调试(通过子类),我发现对于 CKRecordobjectForKey: 确实调用了 objectForKeyedSubscript:。此外,在标记为 @objc 的 Swift 类中实现 subscript 隐式(通过从 NSObject 下降)或显式意味着 subscript 实现为 objectForKeyedSubscript:

这意味着在扩展中的 CKRecord 上实现 subscript 会隐藏默认实现,从而导致堆栈溢出。

关于swift - 在 Swift 中的 CKRecord 上定义下标时发生堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27159950/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com