• Xcode 调试方法总结


     

    前言:编写代码过程中出现错误、异常是不可避免的。通常我们都需要进行大量的调试去寻找、解决问题。这时,熟练掌握调试技巧将很大程度上的提高工作效率。接下来就说说开发过程中Xcode的调试方法。

    1. Enable NSZombie Objects (开启僵尸对象)。 
    这个技巧主要用来追终重复释放的问题。个人认为,ARC推出以来。项目的基本是基于ARC环境。不用开发者主动去调用release去释放对象,所以不用太在意这个方法。这里就不多做介绍了。想了解该方法的同学请 坐飞机 
    2. 断点调试(全局断点、条件断点) 
    一、全局断点:

    NSArray *aa = @[@2,@4];
    NSLog(@"%@",aa[3]);
    • 1
    • 2

    这两行代码,没有添加全局断点时,运行crash,直接就跳到了mian函数,如下图:

    这里写图片描述

    接下来添加全局断点,方法如下图:

    添加全局断点的方法

    添加之后运行,奔溃后,程序停留在了crash那行代码。

    这里写图片描述
    是不是很方便,很省事。哈哈!(ps 不过有的crash,这种方式定位不到)

    二、条件断点:设置断点触发的条件,方便开发者对特定情况进行调试 
    如下图: 
    在for循环中添加一个断点。右击断点选择”Edit BreakPoint”,然后设置断点触发条件。 
    这里写图片描述

    这个例子当 “i==5”时,断点触发,如下图: 
    这里写图片描述

    3. Static Analyzer (静态分析) 
    Static Analyzer主要用于分析内存,避免内存泄漏。主要对以下情况进行分析。 
    未使用的实例变量、未初始化的实例变量、类型不兼容、无法达到的路径、引用空指针 
    使用:command + shift +B,如下图就能轻松找到可能内存泄漏的代码,然后我们根据代码环境进行修复就可以了(ps:有的内存泄漏可能检测不出来,还是需要我们在写代码时对内存这块多留点心。)

    这里写图片描述

    4. LLDB调试器 
    这个方法是我今天主推的方法。比较高级,也更加灵活、方便。 
    随着Xcode5,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。其实Xcode已经帮我们完成了大部分工作,而且很多东西也可以在Xcode中直接看到。所以这里我们只列举常用的命令。 
    打印:p,print的缩写:该命令如果打印的是简单类型则会列出简单类型的的类型和值,如果是对象会打印出对象的地址。 
    po,print Object 的缩写,用于输出OC对象 
    如下如,当运行到断点处时,控制台就会出现LLDB的调试命令行。我们只需在这里进行调试。 
    这里写图片描述

    expr:expression的缩写,可以在调试时动态执行指定表达式,并将结果打印出来。常用于在调试过程中修改变量的值。 
    如上图,你在控制台输入  
    expr a=2 
    你就能看到 
    (NSInteger) $11 = 2 
    这是a的值就被动态改成了2 
    除此之外,还可以使用这个命令生成一个新的对象,如: 
    expr int $b = 0 
    p $b 这条命令用于输出新申明对象的值(注意要加$)

    image: image命令可用于寻址,有多个组合命令,在控制台输入help image可查看image的用法。比较实用的用法是用于寻找栈地址对应的代码位置,下面我们来举个例子:

    NSArray *array = @[@1,@2];
    NSLog(@"%@",array[2]);
    • 1
    • 2

    这段代码很明显会crash,运行之后抛出下面的异常

    2016-03-23 22:26:11.014 Test[3631:136626] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
    *** First throw call stack:
    (
        0   CoreFoundation                      0x0000000104f28f45 __exceptionPreprocess + 165
        1   libobjc.A.dylib                     0x00000001049a2deb objc_exception_throw + 48
        2   CoreFoundation                      0x0000000104e17b14 -[__NSArrayI objectAtIndex:] + 164
        3   Test                                0x00000001044a5829 -[ViewController viewDidLoad] + 265
        4   UIKit                               0x0000000105467cc4 -[UIViewController loadViewIfRequired] + 1198
        5   UIKit                               0x0000000105468013 -[UIViewController view] + 27
        6   UIKit                               0x000000010534151c -[UIWindow addRootViewControllerViewIfPossible] + 61
        7   UIKit                               0x0000000105341c05 -[UIWindow _setHidden:forced:] + 282
        8   UIKit                               0x00000001053534a5 -[UIWindow makeKeyAndVisible] + 42
        9   UIKit                               0x00000001052cd396 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131
        10  UIKit                               0x00000001052d39c3 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1750
        11  UIKit                               0x00000001052d0ba3 -[UIApplication workspaceDidEndTransaction:] + 188
        12  FrontBoardServices                  0x0000000107c83784 -[FBSSerialQueue _performNext] + 192
        13  FrontBoardServices                  0x0000000107c83af2 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
        14  CoreFoundation                      0x0000000104e55011 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
        15  CoreFoundation                      0x0000000104e4af3c __CFRunLoopDoSources0 + 556
        16  CoreFoundation                      0x0000000104e4a3f3 __CFRunLoopRun + 867
        17  CoreFoundation                      0x0000000104e49e08 CFRunLoopRunSpecific + 488
        18  UIKit                               0x00000001052d04f5 -[UIApplication _run] + 402
        19  UIKit                               0x00000001052d530d UIApplicationMain + 171
        20  Test                                0x00000001044a5baf main + 111
        21  libdyld.dylib                       0x000000010764c92d start + 1
        22  ???                                 0x0000000000000001 0x0 + 1
    )
    libc++abi.dylib: terminating with uncaught exception of type NSException
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    现在我怀疑出错的地址是0x00000001044a5829(可根据执行文件名或最小的栈地址判断)为进一步精确定位我们可输入以下命令image lookup --address 0x00000001044a5829 
    命令执行后返回结果如下:

    Address: Test[0x0000000100001829] (Test.__TEXT.__text + 265)
    Summary: Test`-[ViewController viewDidLoad] + 265 at ViewController.m:21
    • 1
    • 2

    由此,我们可以看出出错的地方是ViewController.m文件的第21行。 
    我们还可以使用image lookup命令查看具体的类,如下:

    (lldb) image lookup --type UIView
    Best match found in /Users/jamalping/Library/Developer/Xcode/DerivedData/Test-gviuudbzlyhssmanjxpwhchdbscz/Build/Products/Debug-iphonesimulator/Test.app/Test:
    id = {0x00001e8d}, name = "UIView", byte-size = 8, decl = UIView.h:144, clang_type = "@interface UIView : UIResponder
    @property ( getter = isUserInteractionEnabled,setter = setUserInteractionEnabled:,assign,readwrite,nonatomic ) BOOL userInteractionEnabled;
    @property ( getter = tag,setter = setTag:,assign,readwrite,nonatomic ) NSInteger tag;
    @property ( readonly,getter = layer,setter = <null selector>,nonatomic ) CALayer * layer;
    @property ( readonly,getter = isFocused,setter = <null selector>,nonatomic ) BOOL focused;
    @property ( getter = semanticContentAttribute,setter = setSemanticContentAttribute:,assign,readwrite,nonatomic ) UISemanticContentAttribute semanticContentAttribute;
    @end
    "
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    call 
    call:即调用,如我们在viewDidLoad: 设置一个断点,在程序中断的时候输入call self.view.backgroudColor = [UIColo redColor]继续运行程序,view就变成红色了,在调试的时候灵活运用call命令可以达到事半功倍的效果

  • 相关阅读:
    开发笔记:python与随机数(转)
    如何建立内核级钩子控制操作系统实现程序隐身(转)
    SPOJ 7001. Visible Lattice Points (莫比乌斯反演)
    BZOJ 2301: [HAOI2011]Problem b (莫比乌斯反演)
    HDU 1695 GCD (莫比乌斯反演)
    HDU 4691 Front compression (2013多校9 1006题 后缀数组)
    HDU 4686 Arc of Dream (2013多校9 1001 题,矩阵)
    HDU 1695 GCD (欧拉函数+容斥原理)
    【转】[专题学习][计算几何]
    POJ 1755 Triathlon (半平面交)
  • 原文地址:https://www.cnblogs.com/lan1x/p/8340644.html
Copyright © 2020-2023  润新知