博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 调试心得
阅读量:5884 次
发布时间:2019-06-19

本文共 6454 字,大约阅读时间需要 21 分钟。

hot3.png

修复 bug 占用我们日常开发的大部分时间,熟练的使用调试工具可以给我们节约大部分的时间。

LLDB 的常用命令

expression

expresion 是一个非常常用的命令,我们可以通过这个命令来执行一些表达式,这样我们就不需要重写运行工程了,例如:

(lldb) expression -- self.view.backgroundColor = [UIColor greenColor]  (lldb) expression -- (void)[CATransaction flush] // 用于刷新页面,

我们也可以使用 expression 来输出我们关注的信息

(lldb) expression -O -- self.view //这时候 就会输出对象 UIView,注意 -O 代表输出的是一个对象 ,这里有另外一种简写方式 po.
>

有时候我们自定义的类并没有重写 description 方法,如果我们直接输出这个对象的话可能只会显示这个类名和地址,例如

(lldb) expression -O -- self

这地址并不是我们想要的,我们想要的是这个对象内部信息,这里我推荐一个插件 ,我们可以使用chisel 提供的命令来打印这个对象, 例如

(lldb) pinternals 0x7d2974a0(JChatAboutMeViewController) $4 = {  UIViewController = {    UIResponder = {      NSObject = {        isa = JChatAboutMeViewController      }      _hasOverrideClient = '\0'      _hasOverrideHost = '\0'      _hasInputAssistantItem = '\0'    }    _overrideTransitioningDelegate = nil    _view = nil    _tabBarItem = nil    _navigationItem = 0x7d4abf40    _toolbarItems = nil    _title = nil    _nibName = nil    _nibBundle = nil    _parentViewController = 0x7cb84c00    _childModalViewController = nil    _parentModalViewController = nil    _previousRootViewController = nil    _modalTransitionView = nil    _modalPreservedFirstResponder = nil    _dimmingView = nil    _dropShadowView = nil    _currentAction = nil    _storyboard = nil    _externalObjectsTableForViewLoading = nil    _topLevelObjectsToKeepAliveFromStoryboard = nil    _savedHeaderSuperview = nil    _savedFooterSuperview = nil    _editButtonItem = nil    _searchDisplayController = nil    _strongSearchDisplayController = nil    _modalTransitionStyle = 0    _modalPresentationStyle = 0    _lastKnownInterfaceOrientation = 0    _popoverController = nil    _containerViewInSheet = nil    _recordedContentScrollView = nil    _afterAppearance = nil    _explicitAppearanceTransitionLevel = 0    _interfaceBuilderKeyCommands = nil    _addedKeyCommands = nil    _overrideTraitCollections = nil    _previewSourceViews = nil    _retainCount = 0    _ignoreAppSupportedOrientations = '\0'    _viewHostsLayoutEngine = '\0'    _storyboardIdentifier = nil    _transitioningDelegate = nil    _frozenTraitCollection = nil    overrideUseCustomPresentation = '\0'    _modalPresentationCapturesStatusBarAppearance = '\0'    _disablesAutomaticKeyboardDismissal = '\0'    _ignoresParentMargins = '\0'    _childViewControllers = nil    _customNavigationInteractiveTransitionDuration = 0    _customNavigationInteractiveTransitionPercentComplete = 0    _customTransitioningView = nil    _lastNotifiedTraitCollection = nil    _presentationController = nil    _preferredFocusedItem = nil    _navigationControllerContentOffsetAdjustment = 0    _contentMargin = 16    _topLayoutGuide = nil    _bottomLayoutGuide = nil    _topBarInsetGuideConstraint = nil    _bottomBarInsetGuideConstraint = nil    _storyboardSegueTemplates = nil    _segueResponsibleForModalPresentation = nil    _sourceViewControllerIfPresentedViaPopoverSegue = nil    _modalSourceViewController = nil    _presentedStatusBarViewController = nil    _edgesForExtendedLayout = 15    __childControllerToIgnoreWhileLookingForTransitionCoordinator = nil    _presentingFocusedItem = nil    _storyboardPreviewSegueTemplates = nil    _storyboardCommitSegueTemplates = nil    _storyboardPreviewingRegistrants = nil    __embeddedView = 0xffffffff    __embeddingView = 0x78b909c0    __embeddedDelegate = 0x00007faa    _originalPresentationController = 0x78af3630    _temporaryPresentationController = 0x00007faa  }}

这样我们就能看到这个对象的内部信息了。 chisel 还提供一些便捷的功能,比如打印 pviews 递归打印层级,不过我更喜欢使用 xcode 自带的debug view hierarchy,这样更加直观。

我们可以使用 pvc 递归输出试图控制器的层级关系,例如

(lldb) pvc
, state: appeared, view:
|
, state: appeared, view:
| |
, state: disappeared, view:
not in the window | |
, state: appeared, view:
|
, state: disappeared, view:
not in the window | |
, state: disappeared, view:
not in the window |
, state: disappeared, view:
not in the window | |
, state: disappeared, view: (view not loaded)

通过 pvc 和 pinternals 这样我们就可以在任何地方了解我们所有界面状态了。 在 xcode8 以后,我们也可以通过debug memory graph 来查看程序运行的内存状态。

thread

我们可以使用 thread backtrace 来输出线程的堆栈信息,例如

(lldb) thread backtrace  // 这个命令可以简写为bt* thread #1: tid = 0x14169a, 0x001273e5 JChatSwift`JChatChattingViewController.viewDidLayoutSubviews(self=0x7b6bc560) -> () + 21 at JChatChattingViewController.swift:48, queue = 'com.apple.main-thread', stop reason = breakpoint 7.1  * frame #0: 0x001273e5 JChatSwift`JChatChattingViewController.viewDidLayoutSubviews(self=0x7b6bc560) -> () + 21 at JChatChattingViewController.swift:48    frame #1: 0x00127502 JChatSwift`@objc JChatChattingViewController.viewDidLayoutSubviews() -> () + 34 at JChatChattingViewController.swift:0    frame #2: 0x039dc811 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1598    frame #3: 0x0305c1b9 libobjc.A.dylib`-[NSObject performSelector:withObject:] + 59    frame #4: 0x03791769 QuartzCore`-[CALayer layoutSublayers] + 141    frame #5: 0x03784a47 QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 401    frame #6: 0x0378489d QuartzCore`CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 21    frame #7: 0x0370e49f QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 339    frame #8: 0x0373d290 QuartzCore`CA::Transaction::commit() + 498    frame #9: 0x0373eda0 QuartzCore`CA::Transaction::flush_transaction() + 38    frame #10: 0x0393685c UIKit`_afterCACommitHandler + 375    frame #11: 0x022f676e CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30    frame #12: 0x022f66c7 CoreFoundation`__CFRunLoopDoObservers + 391    frame #13: 0x022da3a6 CoreFoundation`__CFRunLoopRun + 1414    frame #14: 0x022d9bab CoreFoundation`CFRunLoopRunSpecific + 395    frame #15: 0x022d9a0b CoreFoundation`CFRunLoopRunInMode + 123    frame #16: 0x06a1ab4c GraphicsServices`GSEventRunModal + 177    frame #17: 0x06a1a9c7 GraphicsServices`GSEventRun + 80    frame #18: 0x039077fb UIKit`UIApplicationMain + 148    frame #19: 0x001a7ce1 JChatSwift`main + 145 at AppDelegate.swift:15    frame #20: 0x06037799 libdyld.dylib`start + 1

我们可以看到程序停在JChatChattingViewController.swift:48 这一行

watchpoint

监视某个变量的改变,有时候我们想知道一个对象在什么时候被修改了,我们可以使用 watchpoint set var,当var 改变的时候程序就就会停在改变的地方, 如果用 chisel 的话,我们可以使用 wivar 命令来监听值的变化,例如

(lldb) wivar self name

作者:HuminiOS - 极光

原文:

知乎专栏:

转载于:https://my.oschina.net/jpushtech/blog/856202

你可能感兴趣的文章
PHP盛宴——经常使用函数集锦
查看>>
重写 Ext.form.field 扩展功能
查看>>
Linux下的搜索查找命令的详解(locate)
查看>>
MySQL查询优化
查看>>
android app启动过程(转)
查看>>
安装gulp及相关插件
查看>>
如何在Linux用chmod来修改所有子目录中的文件属性?
查看>>
Applet
查看>>
高并发环境下,Redisson实现redis分布式锁
查看>>
关于浏览器的cookie
查看>>
Hyper-V 2016 系列教程30 机房温度远程监控方案
查看>>
笔记:认识.NET平台
查看>>
cocos2d中CCAnimation的使用(cocos2d 1.0以上版本)
查看>>
【吉光片羽】短信验证
查看>>
gitlab 完整部署实例
查看>>
GNS关于IPS&ASA&PIX&Junos的配置
查看>>
影响企业信息化成败的几点因素
查看>>
SCCM 2016 配置管理系列(Part8)
查看>>
struts中的xwork源码下载地址
查看>>
ABP理论学习之仓储
查看>>