2015-09-26 94 views
0

试想一个类水果:如何模仿描述输出?

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> 

正如你所看到的输出是相同的这是我想要的东西。现在我想知道,如果这是模仿它的输出的正确方式,或者我忽略了以下注释中提到的内容。

学分:马特,马丁·R和Vacawama

+1

如何定义你的课吗?如果你不覆盖它,什么会'self.description'打印? –

+0

“这给了我完全相同的输出打印(super.description)会做”不,因为散列不是内存地址。这似乎是一个没有问问题,你真的想要的答案... – matt

+0

我很抱歉让我重写这个问题。 – Mark

回答

1

NSObject不限子类继承的NSObjectdescription方法(其在NSObjectProtocol定义):

class Foo1 : NSObject { } 
print(Foo1()) 
// <MyProject.Foo1: 0x100612fd0> 

这种“默认实现”打印类名称和对象的存储 地址,看例如 Friday Q&A 2013-01-25: Let's Build NSObject,其中显示了Objective-C的实施 怎么可能是这样的:

- (NSString *)description 
{ 
    return [NSString stringWithFormat: @"<%@: %p>", [self class], self]; 
} 

%p格式将指针的值打印为十六进制数 ,后面跟着0x

为了模拟在斯威夫特,我们可以使用

  • 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] 

这适用于“纯夫特班”为好,因为没有使用基金会 方法:

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] 

注意(如已经在上面提到的评论),对象的哈希值 不一定identica l到内存地址。 一个简单的例子是NSArray()其哈希值是元素的只是数量 :

let array = NSArray(objects: 1, 2, 3) 
print(unsafeAddressOf(array)) // 0x00000001020011a0 
print(array.hashValue) // 3 

更新斯威夫特3:

class Bar : CustomStringConvertible { 
    var description : String { 
     let className = String(reflecting: type(of: self)) 
     let address = Unmanaged.passUnretained(self).toOpaque() 
     return "[\(className): \(address)]" 
    } 
} 
+0

令人惊叹的答案马丁R,感谢您的时间和努力。 – Mark

1

使用String(self.hash, radix:16)。您可能需要自行加上0x的前缀。

+1

或者:'String(格式:“%#x”,哈希)','#'格式标志导致'0x'被加在前面:) –

+0

你们都是英雄......不能将它标记为答案(9分钟并计算) – Mark

+1

但是,我猜这是一个误解。哈希不是内存地址。 – matt