Swift 直接使用或在字符串插值中使用时返回不同值的字符串属性

Swift 直接使用或在字符串插值中使用时返回不同值的字符串属性,swift,Swift,我刚刚调试完一种情况,其中一些标签没有显示任何文本,尽管所讨论的字符串肯定包含一个值(它之前打印了这行)。我最终将其限制为根据访问字符串的方式返回不同的值。请注意,我不是在寻找解决这个问题的方法,我是在寻找一个我不知道为什么会发生这种行为的原因 我有一个带有以下可选字符串属性的协议,设置为默认值为nil: protocol SomeProtocol { var titleString: String? { get } } extension SomeProtocol { var

我刚刚调试完一种情况,其中一些标签没有显示任何文本,尽管所讨论的字符串肯定包含一个值(它之前打印了这行)。我最终将其限制为根据访问字符串的方式返回不同的值。请注意,我不是在寻找解决这个问题的方法,我是在寻找一个我不知道为什么会发生这种行为的原因

我有一个带有以下可选字符串属性的协议,设置为默认值为
nil

protocol SomeProtocol {
    var titleString: String? { get }
}

extension SomeProtocol {
    var titleString: String? {
        return nil
    }
}
它是在一个类中实现的,该类包含一个非可选字符串,并在其他地方设置了
title

class SomeClass: SomeProtocol {
    var title: String
    var titleString: String {
        return title
    }
}
当试图从
SomeClass
对象访问titleString的值时,它总是返回
nil
,而不考虑
title
属性。这是通过指定一个标签看到的,如:

label.text = someClassInstance.titleString
但是,当我打印值或设置标签时

label.text = "\(someClassInstance.titleString)"
一切正常,它显示了文本

我已经将这个问题的来源缩小到我用一个非可选属性覆盖可选属性的地方。显然,当我直接访问属性时,它由协议实现返回,而通过字符串插值使用它则返回类1。这种行为背后的真正原因是什么

编辑:要演示此行为,请在Xcode游戏场中运行此要点:

我觉得这与我的解决方案有些相似。在这个问题上,还有两个几乎相同的属性——一个是可选的,另一个是非可选的。我也经历过类似的情况,斯威夫特不知道我想要什么样的财产

SomeClass
中的
titleString
不是覆盖协议中的
titleString
属性。这反映在Xcode的建议中:

您可以像这样访问这两个属性:

someObject.titleString as String // accesses the one in SomeClass
someObject.titleString as String? // accesses the one in the protocol
我的观点是,表达的类型很重要。如果swift期望的表达式类型是
String
,那么它将解析为
SomeClass
中的表达式。如果表达式的预期类型为
String?
,则其计算结果为协议中的类型


这解释了为什么在不使用字符串插值的情况下设置标签文本将调用协议中的属性(
label.text
string?
,因此它需要
string?
),以及为什么使用字符串插值将调用
SomeClass
中的属性(字符串插值需要非可选).

您能发布真实再现问题的代码吗?我在Xcode 9.4游乐场中尝试了您的代码,但两种方式都没有看到
nil
。@rmaddy请尝试将其分配给标签的
text
属性,然后在您的页面中打印标签的
text
playground@rmaddy它显示在本要点的代码中:使用标签的
text
属性可以重现问题。因此如果已知结果是
String?
,则调用返回类型为
String?
标题字符串。如果已知结果是
字符串
,则调用返回类型为
字符串
标题字符串
。我不知道这在某种程度上是否是一个bug,但这足以避免这个问题。啊,我明白了。因此,AppCode中似乎存在一个bug,它(多少可以理解)将
SomeClass.titleString
显示为实现
SomeProtocol.titleString
属性,而不是一个快速的问题。