Xcode Debug调试汇总

未完待续,[继续总结]

LLDB && GDB

lldb与gdb命令对比

常用的Debug快捷键

功能 命令
暂停/继续 cmd + ctrl + Y
断点失效/生效 cmd + Y
控制台显示/隐藏 cmd + shift + Y
光标切换到控制台 cmd + shift + C
清空控制台 cmd + K
step over F6
step into F7
step out F8

技巧一:格式化输出数据

代替NSLog,打印对象的内部属性

技巧二:条件断点(condition)

设置断点触发条件

注意:

// 正确
(BOOL)[pId isEqualToString:@"short-videopage"]

// 报错:error: no known method '-isEqualToString:'; cast the message send to the method's return type
[pId isEqualToString:@"short-videopage"]
复制代码

技巧三:运行中修改变量的值(expr & call)

在调试登录相关的bug时,非常方便,不用担心经常输密码,还输错的尴尬

调试UI,改变指定控件的颜色

技巧四:符号断点(Add Symbolic Breakpoint)

当我们查看一个陌生的项目的时候,我们可以先运行APP,对所有的viewDidLoad函数添加断点,进而了解代码执行路径

Symbol:符号

  • c语言,methodName只需要写函数名,不用写后面的()
  • oc样式,[className methodName] className是类名,methodName是方法名(不区分类方法和实例方法)
  • swift样式,ClassName.methodName

Module模块筛选:可以避免不同库中方法名或者函数名相同 Condition触发条件

这里可以添加一些指定触发条件,比如添加第一个参数(arg3)不能为nil。这里arg4代表第2个参数,以此类推。这里也可以调用方法来判断,但必须是类方法,并且返回值必须为BOOL类型。 样例:找出给[UIImage imageNamed:]传nil的代码。这里就需要设置Symbol为[UIImage imageNamed:],然后Condition设置为$arg3 == nil。这样在运行中如果遇到传nil就会触发断点。

查看某一个函数需要添加断点的符号填写格式(在需要调试的函数打上断点,程序运行走到断点后,从堆栈信息中查看相应函数的格式)

技巧五:全局异常断点(Add Exception Breakpoint)

技巧六:查看整体UI层级结构(debug view hierarchy)

如果电脑配置较低,最好使用chisel插件命令pviews

技巧七:开启僵尸模式(EXC_BAD_ACCESS)

遇到EXC_BAD_ACCESS这个错误,那就意味着你向一个已经释放的对象发送消息。Xcode知道这个对象是什么,所以可以让我们知道这个对象在哪里,以及这是什么时候发生的。当开启僵尸模式后,遇到EXC_BAD_ACCESS,xcode可以帮我们快速定位到出现问题的代码。

开启僵尸模式:

技巧八:查看frame的值

导入@import UIKit

(lldb) p self.view.frame
error: property 'frame' not found on object of type 'UIView *'
error: 1 errors parsing expression
(lldb) e @import UIKit
(lldb) p self.view.frame
(CGRect) $0 = (origin = (x = 0, y = 0), size = (width = 375, height = 667))
复制代码

或者(CGRect)

print (CGRect)[view frame]
(CGRect) $1 = (origin = (x = 0, y = 0), size = (width = 200, height = 100))
复制代码

技巧九:监听所有的点击事件(UIControl、Touch、Gesture)

方法:覆写UIAppliaction

.h文件

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface CustomApplication : UIApplication

@end

NS_ASSUME_NONNULL_END
复制代码

.m文件

#import "CustomApplication.h"

@implementation CustomApplication
-(void)sendEvent:(UIEvent *)event {
    [super sendEvent:event];
}
@end
复制代码

main.m文件

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "CustomApplication.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc,
                                 argv,
                                 NSStringFromClass([CustomApplication class]),
                                 NSStringFromClass([AppDelegate class]));
    }
}
复制代码
方法执行

一次事件可能会执行三次函数:-(void)sendEvent:(UIEvent *)event三次的force有区别


一次事件可能会执行两次函数:-(void)sendEvent:(UIEvent *)event两次的force没区别


响应者链条

1、如果是UIControl事件,集成UIResponder控件(UIButton)消息传递链(倒序)如下图所示


2、如果是UIGestureRecognizer手势事件,集成UIResponder控件(UIView)消息传递链(倒序)如下图所示


3、如果UIControlUIGestureRecognizer同时存在,优先级高

其他工具:1、Chisel

Chisel是faceBook开源的lldb调试命令集合

安装(具体参考

Chisel 使用 homebrew 来安装

brew update
brew install chisel
复制代码

安装完成后,将下面的命令添加到~/.lldbinit中,xcode启动的时候才会加载chisel

command script import /usr/local/opt/chisel/libexec/fblldb.py
复制代码

常用命令

查看帮助

(lldb) help
复制代码

参考:Chisel-LLDB命令插件,让调试更Easy

其他工具:2、Reveal

Reveal 绝对是iOS界面调试利器。使用起来不仅比Xcode自带流畅,而且功能更加多。由于收费,30天过后就没怎么用但是绝对好用。

大约有4中集成方法,详情参加 官网

其他工具:3、FLEX

参考资料:

[译]用 LLDB 调试 Swift 代码

猜你喜欢

转载自juejin.im/post/5c1f9db76fb9a049c30b3ccf