你怎么能模仿描述输出?

时间:2015-09-26 13:09:46

标签: swift class dynamictype

想象一下水果课:

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

2 个答案:

答案 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)]"
    }
}