内容简介:遇到EXC_BAD_ACCESS这个错误,那就意味着你向一个已经释放的对象发送消息。Xcode知道这个对象是什么,所以可以让我们知道这个对象在哪里,以及这是什么时候发生的。当开启僵尸模式后,遇到EXC_BAD_ACCESS,xcode可以帮我们快速定位到出现问题的代码。导入@import UIKit
功能 | 命令 |
---|---|
暂停/继续 | 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
:符号
methodName [className methodName] 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、如果 UIControl
和 UIGestureRecognizer
同时存在,优先级高
其他工具: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 复制代码
其他工具:2、Reveal
Reveal 绝对是iOS界面调试利器。使用起来不仅比Xcode自带流畅,而且功能更加多。由于收费,30天过后就没怎么用但是绝对好用。
大约有4中集成方法,详情参加 官网。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。