iOS开发中实用的lldb命令

p & po

ppo实际都是expression命令,pe --(e就是expression的简写)的别名,poe -o --的简写。

p用于执行一段表达式,如p button.backgroundColor = [UIColor blueColor];用在下面的情况,原本是红色的按钮,会变成蓝色

    UIButton *button = [[UIButton alloc] initWithFrame:(CGRectMake(30, 100, 100, 30))];
    button.backgroundColor = [UIColor redColor];
    [self.view addSubview:button];

这个的好处就是可以在运行之后,我们还可以操控变量的值的来配合调试。比如有些流程会根据值不同,走不同的代码,用p命令就可以在运行后继续修改调试。

po用来输出一个指针指向的对象的值。

(lldb) p button
(UIButton *) $1 = 0x00007fb39c50c1f0
(lldb) po button
<UIButton: 0x7fb39c50c1f0; frame = (30 100; 100 30); opaque = NO; layer = <CALayer: 0x608000031a60>>

比如对于一个按钮,使用p命令,输出的是指针的数据,也就是它执行那个内存的地址,而我们实际需要的信息在指向的对象里,用po就可以直接输出对象信息。

thread backtrace 或 bt

可以用来显示当前的方法调用栈信息。虽然在Xcode里可以查看,但操作可能没有在这里来的快捷。

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
  * frame #0: 0x0000000107df7562 TestDemo`-[ViewController viewDidLoad](self=0x00007fb39c405600, _cmd="viewDidLoad") at ViewController.m:28
    frame #1: 0x0000000108f26cca UIKit`-[UIViewController loadViewIfRequired] + 1235
    frame #2: 0x0000000108f2710a UIKit`-[UIViewController view] + 27
    frame #3: 0x0000000108def63a UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 65
    frame #4: 0x0000000108defd20 UIKit`-[UIWindow _setHidden:forced:] + 294
    frame #5: 0x0000000108e02b6e UIKit`-[UIWindow makeKeyAndVisible] + 42
    frame #6: 0x0000000108d7c31f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
    frame #7: 0x0000000108d82584 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
    frame #8: 0x0000000108d7f793 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182
    frame #9: 0x000000010bfc35f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    frame #10: 0x000000010bfc346d FrontBoardServices`-[FBSSerialQueue _performNext] + 186
    frame #11: 0x000000010bfc37f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
    frame #12: 0x0000000108906c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #13: 0x00000001088ec0cf CoreFoundation`__CFRunLoopDoSources0 + 527
    frame #14: 0x00000001088eb5ff CoreFoundation`__CFRunLoopRun + 911
    frame #15: 0x00000001088eb016 CoreFoundation`CFRunLoopRunSpecific + 406
    frame #16: 0x0000000108d7e02f UIKit`-[UIApplication _run] + 468
    frame #17: 0x0000000108d840d4 UIKit`UIApplicationMain + 159
    frame #18: 0x0000000107df79cf TestDemo`main(argc=1, argv=0x00007fff57e085c0) at main.m:14
    frame #19: 0x000000010b85865d libdyld.dylib`start + 1
(lldb) 

watchpoint

这个断点类型没法通过界面添加而且很有用。使用watchpoint可以用来观察一个变量或者地址,只要变量发生变化就触发断点。

有些时候,我们会发现某个对象的值和我们预期的不一样,可是又不知道是哪个环节修改了这个值,如果一个个的查会特别麻烦。而有了watchpoint事情就简单了。

但是它只能观察这个指针本身,不能指针指向的对象的变化,所以用处大大受限。比如watchpoint set variable button,那么:button.backgroundColor = [UIColor blackColor];不会触发watchpoint,而button = nil;会变。

2017.6.8更新


1、 可以使用内存直接打印,比如输出了一个按钮:

Printing description of $18:
<UIButton: 0x7fdb44d16dc0; frame = (100 60; 100 40); opaque = NO; layer = <CALayer: 0x600000037140>>

这个是使用Debug View Hierarchy查看的时候,用鼠标操纵打印的。如果你想看UIButton内部的其他属性怎么办?比如查看enabled属性。

(lldb) po [0x7fdb44d16dc0 isEnabled]
0x0000000000000101

使用po + 执行方法的形式,因为enabled属性的getter方法是isEnabled,所以用了isEnabled,而不是enabled

2、 使用p/po命令来声明一个变量:

Printing description of $9:
<UIButton: 0x7feadc520090; frame = (125 0; 125 40); opaque = NO; tag = 1001; layer = <CALayer:0x60000023aec0>>

(lldb) po id $myButton = [0x7feadc520090 self]

直接等于内存地址是不行的,所以搞了个self方法把对象返回。注意声明变量的时候,前面是带了一个符号$的,使用的时候也需要:

(lldb) po $myButton
<UIButton: 0x7feadc520090; frame = (125 0; 125 40); opaque = NO; tag = 1001; layer = <CALayer: 0x60000023aec0>>

有了这些,可以更方便的使用lldb来查看和探究对象的性质了!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 2,004评论 0 12
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,134评论 30 470
  • 一、expression expression命令的作用是执行一个表达式,并将表达式返回的结果输出。express...
    boundlessocean阅读 1,030评论 0 2
  • 笋干是取春天刚出土的笋宝宝,去其外壳,用清水煮软之后,切成丝。在阳光下晒干之后,在密封包装下,可以存放几个月。 笋...
    Meekdai阅读 509评论 0 0