String(describing: MyNSObject.self)
总是会返回“MyNSObject”吗?
有些开发者写道:
// identifier is "MyViewController"
let controller = storyboard.instantiateViewController(withIdentifier: String(describing: MyViewController.self)) as! MyViewController
// identifier is "MyTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: MyTableViewCell.self), for: indexPath) as! MyTableViewCell
目前可行,因为使用String(describing: MyNSObject.self)
正在返回"MyNSObject"
。
但我们是在定义行为还是未定义行为的情况下? public init<Subject>(describing instance: Subject)
的文档内容为:
/// - If `instance` conforms to the `TextOutputStreamable` protocol, the
/// result is obtained by calling `instance.write(to: s)` on an empty
/// string `s`.
/// - If `instance` conforms to the `CustomStringConvertible` protocol, the
/// result is `instance.description`.
/// - If `instance` conforms to the `CustomDebugStringConvertible` protocol,
/// the result is `instance.debugDescription`.
/// - An unspecified result is supplied automatically by the Swift standard
/// library.
我担心我们可能处于未指明的结果情况,不是吗?
注1:我们实际实施的是使用protocol
扩展程序,其实现接近static var identifier: String { return String(describing: Self.self) }
。
注意2:NSStringFromClass(Self.self as AnyClass).substring(from: NSStringFromClass(Self.self as AnyClass).range(of: ".")!.upperBound)
可能是明确定义的String(describing: Self.self)
,但它看起来很丑陋。
注意3:即使覆盖description
和debugDescription
的{{1}}和MyViewController
显然也不足以改变MyTableViewCell
。
目前使用Swift 3.1并在可用时移至Swift 4。
答案 0 :(得分:1)
我现在可以记得的唯一描述此行为的官方文档可以在Xcode发行说明中找到:
Swift增强和更改
...
现在输入名称和
enum
个案String
。debugPrint
或String(reflecting:)
仍可用于获取完全限定名称。 例如:enum Fruit { case Apple, Banana, Strawberry } print(Fruit.Apple) // “Apple” debugPrint(Fruit.Apple) // “MyApp.Fruit.Apple”)
(21788604)
(这是Xcode 7.0部分描述Swift 1.2到2.0的增强和更改。因此,转换为String
表示使用String.init(_:)
,现在它是String.init(describing:)
。)
因此,Swift的一些核心成员意识到这种被故意改变的行为。如果Swift团队改变它,我希望在swift.org或者一些公告中进行一些讨论。