recursiveDescription method in Swift?

2019-03-08 09:56发布

Is there a way to use [self.view recursiveDescription] in Swift? I am trying to use this method but I am getting the following error:

'UIView' does not have a member named 'recursiveDescription'

Any suggestions?

8条回答
相关推荐>>
2楼-- · 2019-03-08 10:36
expression -l objc -O -- [`self.view` recursiveDescription]

There is needed enter it in Objective-C format because UIKit is in Objective-C framework.

Recursive description only exists for debugging purposes. It's not part of the public API and so isn't available to Swift

And Swift is a strict language and doesn't allow you to call functions that haven't been strictly defined.

Objective-C, it's a dynamic language so you can call functions like this.

So what we need to do is to tell the debugger to evaluate this expression in an Objective-C syntax

And the way to do that is to use expression with the option - l objc

-O, tell the debugger that we also want the debug description the same as po would do and -- to indicate that there are no more options.

We need to put put [self.view] view in back ticks.

[`self.view`]

Back ticks is like a preproccess step that says first, evaluate the contents of this in the current frame and insert the result, and then we can evaluate the rest.

My answer is taken from WWDC 2018 Session 412 advanced debugging with Xcode and lldb.

查看更多
戒情不戒烟
3楼-- · 2019-03-08 10:38

Add to the bridging header a declaration of a category of UIView with that method.

查看更多
我欲成王,谁敢阻挡
4楼-- · 2019-03-08 10:40

If you want to display the view hierarchy in lldb, you do not have to add any categories or bridging headers or anything like that. When debugging Objective-C code, one would generally use the following command at the (lldb) prompt:

po [[UIWindow keyWindow] recursiveDescription]

If, though, you've paused in a Swift frame, lldb may expect a Swift expression. You can, though, explicitly tell expr (the po abbreviation is actually calling expression) which language the expression is in:

expr -l objc++ -O -- [[UIWindow keyWindow] recursiveDescription]

The same patterns occur in iOS 8, when viewing the view controller hierarchy, using:

po [UIViewController _printHierarchy]

or, in Swift frame:

expr -l objc++ -O -- [UIViewController _printHierarchy]

In WWDC 2018 Advanced Debugging with Xcode, they suggest getting yourself away from this complicated expr syntax by defining an alias, poc, by creating a text file, ~/.lldbinit with the following line:

command alias poc expression -l objc -O --

Then you can do things like:

poc [UIViewController _printHierarchy]

It's worth noting that Xcode 8 introduced the view debugger (click on view debug button), offering a more interactive way to analyze the view hierarchy, largely eliminating the need for the LLDB recursiveDescription of the view hierarchy. For more information see WWDC 2016 video Visual Debugging with Xcode. Admittedly, sometimes we end up having to fall back to the recursiveDescription technique shown above, but most of the time the view debugger makes this a far more natural, intuitive process.

And in Xcode 9, they've expanded this view debugger so it now includes the relevant view controllers, too:

enter image description here

查看更多
干净又极端
5楼-- · 2019-03-08 10:43
po view.value(forKey: "recursiveDescription")!
查看更多
可以哭但决不认输i
6楼-- · 2019-03-08 10:46

First add a category @interface without @implementation in your bridging header.

@interface UIView (Debug)
- (id)recursiveDescription;
- (id)_autolayoutTrace;  // This one is even sweeter
@end

then in your console

po self.recursiveDescription() as NSString
po self._autolayoutTrace() as NSString

The key here is as NSString not as String

查看更多
forever°为你锁心
7楼-- · 2019-03-08 10:46

Building on @Rob Mayoff's answer:

extension UIView {

   /**
    Wrapper for useful debugging description of view hierarchy
   */
   var recursiveDescription: NSString {
       return value(forKey: "recursiveDescription") as! NSString
   }

}
查看更多
登录 后发表回答