想象一下水果课:
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
答案 0 :(得分:1)
使用String(self.hash, radix:16)
。您可能需要自己加0x
前缀。
答案 1 :(得分:1)
NSObject
的任何子类都继承了
NSObject
的{{3}}方法(在NSObjectProtocol
中定义):
class Foo1 : NSObject { }
print(Foo1())
// <MyProject.Foo1: 0x100612fd0>
此“默认实现”打印类名和内存
例如,参见对象的地址
description
,其中显示了Objective-C的实现方式
可能看起来像:
- (NSString *)description
{
return [NSString stringWithFormat: @"<%@: %p>", [self class], self];
}
%p
格式将指针的值打印为十六进制数,
前面是0x
。
要在Swift中模仿,我们可以使用
String(reflecting: self.dynamicType)
以字符串形式返回完全限定的类名,unsafeAddressOf(self)
返回指向存储的指针
对象。示例(使用方括号[]
来演示
使用了重写方法):
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]
这也适用于“纯粹的Swift课程”,因为没有基础 使用方法:
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
Swift 3的更新:
class Bar : CustomStringConvertible {
var description : String {
let className = String(reflecting: type(of: self))
let address = Unmanaged.passUnretained(self).toOpaque()
return "[\(className): \(address)]"
}
}