您如何模仿描述输出?
How can you mimic the description output?
想象一个class水果:
class Fruit: NSObject {
override var description:String {
return super.description
}
}
var apple = Fruit()
var banana = Fruit()
print(apple) // Output: <MyProject.Fruit: 0x7fa719627e00>
print(banana) // Output: <MyProject.Fruit: 0x7fa71962dab0>
问题:如何模仿这个输出?
我目前有:
class Fruit: NSObject {
override var description:String {
print(super.description)
return "<\(NSStringFromClass(self.dynamicType)): 0x\(String(self.hash, radix:16))>"
}
}
现在输出如下:
<MyProject.Fruit: 0x7fb958c289a0>
<MyProject.Fruit: 0x7fb958c289a0>
<MyProject.Fruit: 0x7fb958c22df0>
<MyProject.Fruit: 0x7fb958c22df0>
如您所见,输出与我想要的相同。现在我想知道这是否是模仿其输出的正确方法,或者我忽略了下面评论中提到的内容。
致谢:Matt、Martin R 和 Vacawama
使用String(self.hash, radix:16)
。您可能需要自己添加 0x
前缀。
NSObject
的任何子class 继承
description
NSObject
方法(在 NSObjectProtocol
中定义):
class Foo1 : NSObject { }
print(Foo1())
// <MyProject.Foo1: 0x100612fd0>
这个"default implementation"打印class名字和内存
对象的地址,例如参见
Friday Q&A 2013-01-25: Let's Build NSObject,其中显示了 Objective-C 的实现方式
可能看起来像:
- (NSString *)description
{
return [NSString stringWithFormat: @"<%@: %p>", [self class], self];
}
%p
格式将指针的值打印为十六进制数,
前面有 0x
.
为了模仿 Swift,我们可以使用
String(reflecting: self.dynamicType)
其中 returns 作为字符串的完全限定 class 名称,以及
unsafeAddressOf(self)
其中 returns 指向存储的指针
对象的。
示例(使用方括号 []
来证明
使用重写方法):
class Foo2 : NSObject {
override var description : String {
let className = String(reflecting: self.dynamicType)
let address = unsafeAddressOf(self)
return String(format: "[%@: %p]", className, address)
}
}
print(Foo2())
// [MyProject.Foo2: 0x100613310]
class Foo3 : Foo2 { }
print(Foo3())
// [MyProject.Foo3: 0x102000540]
这也适用于 "pure Swift classes",因为没有 Foundation
使用方法:
class Bar : CustomStringConvertible {
var description : String {
let className = String(reflecting: self.dynamicType)
let address = unsafeAddressOf(self)
return String(format: "[%@: %p]", className, address)
}
}
print(Bar())
// [MyProject.Bar: 0x102001200]
注意(上面评论中已经提到),哈希值
对象的地址不一定与内存地址相同。
一个简单的例子是 NSArray()
其散列值只是数字
元素数:
let array = NSArray(objects: 1, 2, 3)
print(unsafeAddressOf(array)) // 0x00000001020011a0
print(array.hashValue) // 3
Swift3 的更新:
class Bar : CustomStringConvertible {
var description : String {
let className = String(reflecting: type(of: self))
let address = Unmanaged.passUnretained(self).toOpaque()
return "[\(className): \(address)]"
}
}
想象一个class水果:
class Fruit: NSObject {
override var description:String {
return super.description
}
}
var apple = Fruit()
var banana = Fruit()
print(apple) // Output: <MyProject.Fruit: 0x7fa719627e00>
print(banana) // Output: <MyProject.Fruit: 0x7fa71962dab0>
问题:如何模仿这个输出?
我目前有:
class Fruit: NSObject {
override var description:String {
print(super.description)
return "<\(NSStringFromClass(self.dynamicType)): 0x\(String(self.hash, radix:16))>"
}
}
现在输出如下:
<MyProject.Fruit: 0x7fb958c289a0>
<MyProject.Fruit: 0x7fb958c289a0>
<MyProject.Fruit: 0x7fb958c22df0>
<MyProject.Fruit: 0x7fb958c22df0>
如您所见,输出与我想要的相同。现在我想知道这是否是模仿其输出的正确方法,或者我忽略了下面评论中提到的内容。
致谢:Matt、Martin R 和 Vacawama
使用String(self.hash, radix:16)
。您可能需要自己添加 0x
前缀。
NSObject
的任何子class 继承
description
NSObject
方法(在 NSObjectProtocol
中定义):
class Foo1 : NSObject { }
print(Foo1())
// <MyProject.Foo1: 0x100612fd0>
这个"default implementation"打印class名字和内存 对象的地址,例如参见 Friday Q&A 2013-01-25: Let's Build NSObject,其中显示了 Objective-C 的实现方式 可能看起来像:
- (NSString *)description
{
return [NSString stringWithFormat: @"<%@: %p>", [self class], self];
}
%p
格式将指针的值打印为十六进制数,
前面有 0x
.
为了模仿 Swift,我们可以使用
String(reflecting: self.dynamicType)
其中 returns 作为字符串的完全限定 class 名称,以及unsafeAddressOf(self)
其中 returns 指向存储的指针 对象的。
示例(使用方括号 []
来证明
使用重写方法):
class Foo2 : NSObject {
override var description : String {
let className = String(reflecting: self.dynamicType)
let address = unsafeAddressOf(self)
return String(format: "[%@: %p]", className, address)
}
}
print(Foo2())
// [MyProject.Foo2: 0x100613310]
class Foo3 : Foo2 { }
print(Foo3())
// [MyProject.Foo3: 0x102000540]
这也适用于 "pure Swift classes",因为没有 Foundation 使用方法:
class Bar : CustomStringConvertible {
var description : String {
let className = String(reflecting: self.dynamicType)
let address = unsafeAddressOf(self)
return String(format: "[%@: %p]", className, address)
}
}
print(Bar())
// [MyProject.Bar: 0x102001200]
注意(上面评论中已经提到),哈希值
对象的地址不一定与内存地址相同。
一个简单的例子是 NSArray()
其散列值只是数字
元素数:
let array = NSArray(objects: 1, 2, 3)
print(unsafeAddressOf(array)) // 0x00000001020011a0
print(array.hashValue) // 3
Swift3 的更新:
class Bar : CustomStringConvertible {
var description : String {
let className = String(reflecting: type(of: self))
let address = Unmanaged.passUnretained(self).toOpaque()
return "[\(className): \(address)]"
}
}