什么是Swift相当于 - [NSObject描述]?

时间:2014-06-08 17:09:42

标签: swift

在Objective-C中,可以在他们的类中添加description方法以帮助调试:

@implementation MyClass
- (NSString *)description
{
    return [NSString stringWithFormat:@"<%@: %p, foo = %@>", [self class], foo _foo];
}
@end

然后在调试器中,你可以这样做:

po fooClass
<MyClass: 0x12938004, foo = "bar">

Swift中的等价物是什么? Swift的REPL输出可能会有所帮助:

  1> class MyClass { let foo = 42 }
  2> 
  3> let x = MyClass()
x: MyClass = {
  foo = 42
}

但我想覆盖此行为以便打印到控制台:

  4> println("x = \(x)")
x = C11lldb_expr_07MyClass (has 1 child)

有没有办法清理这个println输出?我已经看过Printable协议:

/// This protocol should be adopted by types that wish to customize their
/// textual representation.  This textual representation is used when objects
/// are written to an `OutputStream`.
protocol Printable {
    var description: String { get }
}

我认为这会自动被&#34;看到&#34; println,但似乎并非如此:

  1> class MyClass: Printable {
  2.     let foo = 42
  3.     var description: String { get { return "MyClass, foo = \(foo)" } }
  4. }   
  5> 
  6> let x = MyClass()
x: MyClass = {
  foo = 42
}
  7> println("x = \(x)")
x = C11lldb_expr_07MyClass (has 1 child)

而我必须明确地称之为描述:

 8> println("x = \(x.description)")
x = MyClass, foo = 42

有更好的方法吗?

7 个答案:

答案 0 :(得分:103)

要在Swift类型上实现此功能,您必须实现CustomStringConvertible协议,然后实现名为description的字符串属性。

例如:

class MyClass: CustomStringConvertible {
    let foo = 42

    var description: String {
        return "<\(type(of: self)): foo = \(foo)>"
    }
}

print(MyClass()) // prints: <MyClass: foo = 42>

注意:type(of: self)获取当前实例的类型,而不是显式写入“MyClass”。

答案 1 :(得分:53)

在Swift中使用CustomStringConvertibleCustomDebugStringConvertible协议的示例:

<强> PageContentViewController.swift

import UIKit

class PageContentViewController: UIViewController {

    var pageIndex : Int = 0

    override var description : String { 
        return "**** PageContentViewController\npageIndex equals \(pageIndex) ****\n" 
    }

    override var debugDescription : String { 
        return "---- PageContentViewController\npageIndex equals \(pageIndex) ----\n" 
    }

            ...
}

<强> ViewController.swift

import UIKit

class ViewController: UIViewController
{

    /*
        Called after the controller's view is loaded into memory.
    */
    override func viewDidLoad() {
        super.viewDidLoad()

        let myPageContentViewController = self.storyboard!.instantiateViewControllerWithIdentifier("A") as! PageContentViewController
        print(myPageContentViewController)       
        print(myPageContentViewController.description)
        print(myPageContentViewController.debugDescription)
    }

          ...
}

打印出来:

**** PageContentViewController
pageIndex equals 0 ****

**** PageContentViewController
pageIndex equals 0 ****

---- PageContentViewController
pageIndex equals 0 ----

注意:如果您的自定义类不是从 UIKit Foundation 库中包含的任何类继承,那么请将其继承NSObject类或使其符合CustomStringConvertibleCustomDebugStringConvertible协议。

答案 2 :(得分:35)

只需使用CustomStringConvertiblevar description: String { return "Some string" }

即可

适用于Xcode 7.0 beta

class MyClass: CustomStringConvertible {
  var string: String?


  var description: String {
     //return "MyClass \(string)"
     return "\(self.dynamicType)"
  }
}

var myClass = MyClass()  // this line outputs MyClass nil

// and of course 
print("\(myClass)")

// Use this newer versions of Xcode
var description: String {
    //return "MyClass \(string)"
    return "\(type(of: self))"
}

答案 3 :(得分:20)

CustomStringConvertible 相关的答案是可行的方法。就个人而言,为了使类(或结构)定义尽可能干净,我还要将描述代码分成单独的扩展名:

&#xA;&#xA;
  class foo { &#XA; //只是基本的foo类。&#xA; var bar =“Humbug!”&#xA;}&#xA;&#xA;扩展名foo:CustomStringConvertible {&#xA; var description:String {&#xA;返回栏&#xA; }&#xA;}&#xA;&#xA;让xmas = foo()&#xA; print(xmas)//打印“Humbug!”&#xA;  
&#xA ;

答案 4 :(得分:8)

class SomeBaseClass: CustomStringConvertible {

    //private var string: String = "SomeBaseClass"

    var description: String {
        return "\(self.dynamicType)"
    }

    // Use this in newer versions of Xcode
    var description: String {
        return "\(type(of: self))"
    }

}

class SomeSubClass: SomeBaseClass {
    // If needed one can override description here

}


var mySomeBaseClass = SomeBaseClass()
// Outputs SomeBaseClass
var mySomeSubClass = SomeSubClass()
// Outputs SomeSubClass
var myOtherBaseClass = SomeSubClass()
// Outputs SomeSubClass

答案 5 :(得分:4)

struct WorldPeace: CustomStringConvertible {
    let yearStart: Int
    let yearStop: Int

    var description: String {
        return "\(yearStart)-\(yearStop)"
    }
}

let wp = WorldPeace(yearStart: 2020, yearStop: 2040)
print("world peace: \(wp)")

// outputs:
// world peace: 2020-2040

答案 6 :(得分:3)

如上所述here,您还可以使用Swift的反射功能,通过使用此扩展程序使您的类生成自己的描述:

extension CustomStringConvertible {
    var description : String {
        var description: String = "\(type(of: self)){ "
        let selfMirror = Mirror(reflecting: self)
        for child in selfMirror.children {
            if let propertyName = child.label {
                description += "\(propertyName): \(child.value), "
            }
        }
        description = String(description.dropLast(2))
        description += " }"
        return description
    }
}