2015-09-26 99 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