2014-06-08 20 views
126

Trong Objective-C, người ta có thể thêm một phương pháp description đến lớp học của họ để hỗ trợ trong gỡ lỗi:Tương đương Swift là gì - [Mô tả NSObject]?

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

Sau đó, trong chương trình gỡ rối, bạn có thể làm:

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

tương đương trong Swift là gì ? sản lượng REPL Swift có thể hữu ích:

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

Nhưng tôi muốn thay đổi hành vi này để in ra cửa sổ Console:

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

Có cách nào để làm sạch println sản lượng này? Tôi đã nhìn thấy các Printable giao thức:

/// 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 } 
} 

I figured này tự động sẽ được "nhìn thấy" bởi println nhưng nó không xuất hiện là trường hợp:

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) 

Và thay vào đó tôi phải gọi một cách rõ ràng mô tả:

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

Có cách nào tốt hơn không?

Trả lời

76

Thông qua một số thử nghiệm, tôi đã phát hiện ra rằng các giao thức PrintableDebugPrintable hoạt động khi biên dịch một ứng dụng thực tế, nhưng không phải trong REPL hoặc Sân chơi.

Side Lưu ý: Mã bạn viết là đúng, nhưng trong trường hợp này, bạn có thể tìm cho DebugPrintable


Swift đã đổi tên các giao thức này được CustomStringConvertibleCustomDebugStringConvertible - mặc dù các trình biên dịch hiện helpfully cho bạn hoàn thành công việc mà :)

+3

Tìm thấy tuyệt vời! Tôi sẽ gửi một bản in ra-ra-đa của "swift -i sample.swift" và "swift sample.swift && sample" khác nhau. – Jason

+0

Cảm ơn bạn đã thông tin về điều đó. Tôi đã cố gắng in ra trong một sân chơi và thực sự nó không hoạt động ngay bây giờ. Tốt nó nghe nó hoạt động trong một ứng dụng. –

+0

Có thể in không hoạt động trong sân chơi, nhưng iff lớp xuống từ NSObject – dar512

50

Ví dụ về sử dụng CustomStringConvertibleCustomDebugStringConvertible giao thức trong Swift:

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) 
    } 

      ... 
} 

nào in ra:

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

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

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

Lưu ý: nếu bạn có một lớp tùy chỉnh mà không kế thừa từ bất kỳ lớp trong UIKit hoặc Foundation thư viện, sau đó làm cho nó kế thừa của NSObject lớp hoặc làm cho nó phù hợp với CustomStringConvertibleCustomDebugStringConvertible giao thức.

33

Chỉ cần sử dụng CustomStringConvertiblevar description: String { return "Some string" }

công trình trong 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))" 
} 
7
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 
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 
19

Những câu trả lời liên quan đến CustomStringConvertible là con đường để đi. Cá nhân, để giữ định nghĩa lớp (hoặc cấu trúc) càng rõ ràng càng tốt, tôi cũng sẽ tách mã mô tả thành một phần mở rộng riêng biệt:

class foo { 
    // Just the basic foo class stuff. 
    var bar = "Humbug!" 
} 

extension foo: CustomStringConvertible { 
    var description: String { 
     return bar 
    } 
} 

let xmas = foo() 
print(xmas) // Prints "Humbug!" 
Các vấn đề liên quan