这篇文章主要介绍“Xcode常用命令有哪些”,在日常操作中,相信很多人在Xcode常用命令有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Xcode常用命令有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
1. p 命令
-- ('expression --') Evaluate an expression on the current thread.
Displays any returned value with LLDB's default formatting.
p 命令是 print 命令的简写,使用p 命令可以查看基本数据类型的值,但是如果 使用 p 命令 查看的是对象,那么只会返回对象的指针地址。 p 命令后面除了可以接 变量、常量,还可以接 表达式。(❌但是不可以使用宏❌)
2. po 命令
po 命令可以理解为打印对象。功能与 p 命令类似,所以也是可以打印 常量、变量,打印表达式返回的对象等。(❌也不可以打印宏❌)
p 和 po 使用范例
当然,这些打印功能,除了使用命令外,我们也可以使用左侧区域,点击变量右键---> print Description of “xxx”:
Paste_Image.png
当然还有其他的打印方法:
3.expr 命令
expr 是 expression 的简写, 使用expr 命令,能够在调试时,动态的执行赋值表达式,同时打印出结果。我们可以在调试时,动态的修改变量的值,这在调试想要让应用执行异常路径(如执行某个else 情况)很有用。
(lldb) p i
(NSInteger) 17 = 5
(lldb) po i
5
4.call 命令
上面是动态修改变量的值, Xcode 还支持动态调用函数。在控制台执行该命令,可以在不修改代码,不重新编译的情况下,修改界面上的视图。 这里有一个动态将cell 的某个子视图移除的范例:
(lldb) po cell.contentView.subviews
<__NSArrayM 0x60800005f5f0>(
<UILabel: 0x7f91f4f18c90; frame = (5 5; 300 25); text = '2 - Drawing index is top ...'; userInteractionEnabled = NO; tag = 1; layer = <_UILabelLayer: 0x60800009ff40>>,
<UIImageView: 0x7f91f4d20050; frame = (105 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x60000003ff60>>,
<UIImageView: 0x7f91f4f18f10; frame = (200 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 3; layer = <CALayer: 0x608000039860>>
)(lldb) call [label removeFromSuperview]
(lldb) po cell.contentView.subviews
<__NSArrayM 0x600000246de0>(
<UIImageView: 0x7f91f4d20050; frame = (105 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 2; layer = <CALayer: 0x60000003ff60>>,
<UIImageView: 0x7f91f4f18f10; frame = (200 20; 85 85); opaque = NO; userInteractionEnabled = NO; tag = 3; layer = <CALayer: 0x608000039860>>
)
5.bt命令
bt
命令 可以打印出线程的堆栈信息,该信息比左侧的Debug Navigator 看到的还要详细一些。
bt
命令是打印当前线程的堆栈信息
(lldb) bt
* thread #1: tid = 0x27363, 0x000000010d204125 TestDemo-[FifthViewController tableView:cellForRowAtIndexPath:](self=0x00007f91f4e153c0, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007f91f5889600, indexPath=0xc000000000400016) + 2757 at FifthViewController.m:91, queue = 'com.apple.main-thread', stop reason = breakpoint 6.1 * frame #0: 0x000000010d204125 TestDemo
-[FifthViewController tableView:cellForRowAtIndexPath:](self=0x00007f91f4e153c0, _cmd="tableView:cellForRowAtIndexPath:", tableView=0x00007f91f5889600, indexPath=0xc000000000400016) + 2757 at FifthViewController.m:91
frame #1: 0x0000000111d0a7b5 UIKit-[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 757 frame #2: 0x0000000111d0aa13 UIKit
-[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
frame #3: 0x0000000111cde47d UIKit-[UITableView _updateVisibleCellsNow:isRecursive:] + 3295 frame #4: 0x0000000111d13d95 UIKit
-[UITableView _performWithCachedTraitCollection:] + 110
frame #5: 0x0000000111cfa5ef UIKit-[UITableView layoutSubviews] + 222 frame #6: 0x0000000111c61f50 UIKit
-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1237
frame #7: 0x00000001117a5cc4 QuartzCore-[CALayer layoutSublayers] + 146 frame #8: 0x0000000111799788 QuartzCore
CA::Layer::layout_if_needed(CA::Transaction) + 366
frame #9: 0x0000000111799606 QuartzCoreCA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24 frame #10: 0x0000000111727680 QuartzCore
CA::Context::commit_transaction(CA::Transaction) + 280
frame #11: 0x0000000111754767 QuartzCoreCA::Transaction::commit() + 475 frame #12: 0x00000001117550d7 QuartzCore
CA::Transaction::observer_callback(__CFRunLoopObserver, unsigned long, void) + 113
frame #13: 0x0000000110743e17 CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23 frame #14: 0x0000000110743d87 CoreFoundation
__CFRunLoopDoObservers + 391
frame #15: 0x0000000110728b9e CoreFoundation__CFRunLoopRun + 1198 frame #16: 0x0000000110728494 CoreFoundation
CFRunLoopRunSpecific + 420
frame #17: 0x0000000114390a6f GraphicsServicesGSEventRunModal + 161 frame #18: 0x0000000111b9d964 UIKit
UIApplicationMain + 159
frame #19: 0x000000010d21294f TestDemomain(argc=1, argv=0x00007fff529fe620) + 111 at main.m:14 frame #20: 0x000000011458a68d libdyld.dylib
start + 1
(lldb)
bt all
命令是打印所有线程的堆栈信息。打印出来的信息太多,就不展示了!
6.image 命令
image list
命令可以列出当前App中的所有module(这个module 在后面符号断点时有用到),可以查看某一个地址对应的代码位置。 除了 image list
还有 image add
、image lookup
等命令,可以自行查看。 当遇到crash 时,查看线程栈,只能看到栈帧的地址,使用 image lookup –address 地址
可以方便的定位到这个地址对应的代码行。
断点
Xcode 中的断点也是很有学问的,有普通断点、条件断点、符号断点、异常断点等很多种。
1.普通断点
打一个普通断点,只需要找到对应的行,在代码左侧(行号上)点击一下即可。
2.条件断点
条件断点是一种很有用的断点,特别是在for 循环中。如果我们需要在i = 5 时添加断点,其他时候不加,那么就可以使用条件断点。条件断点是在普通断点上 右键,选择 Edit Breakpoint...
,再设置一个条件即可
编辑普通断点
添加条件
3.符号断点
符号断点就是 Symbolic Breakpoint
,其实是针对某一个特定函数的断点,可以是一个 OC函数,也可以是 C++函数。 添加的地方如下:
符号断点
符号断点条件
Symbol 栏 可以填 [类名 方法名]或者 方法名 ,module 也是选填项,它就是上面 image
命令中列出来的module。 例如 ,我们如果只填一个viewDidLoad,那么就会在所有类(包括第三方库)的viewDidLoad 处打断点。
符号断点在调试一些没有源码的模块时比较有用,比如调试一个第三方提供的Lib库,或者系统的模块,可以在相应函数处下断点,可以大概调试清楚程序的运行流程,也可以在断点的时候查看到参数信息。
4.异常断点
如果程序运行就崩溃,我们可以打一个异常断点,这样崩溃时就会触发断点,很容易定位到问题所在,也能看到更多的崩溃相关信息,如Log,函数调用栈。
异常断点
可以修改异常断点的条件
注意: 有的程序或者有的功能可能会使用异常来组织程序逻辑,比如调用AVAudioPlayer ,运行到 AVAudioPlayer 时,就会导致断点被触发。我们可以修改 Exception 参数,或者取消掉异常断点来解决。
5.Watch 断点
当某个变量发生变化的时候会触发。 创建一个Watch断点:
到此,关于“Xcode常用命令有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!