• 分享一段代码帮助进行调试

    有时程序崩溃根本不知错误发生在什么地方。比如程序出现EXEC_BAD_ACCESS的时候,虽然大部分情况使用设定NSZombieEnabled环境变量可以帮助你找到问题的所在,但少数情况下,即使设定了NSZombieEnabled环境变量,还是不知道程序崩溃在什么地方。那么就需要使用下列代码进行帮助了:

    1
    2
    3
    4
    5
    6
    #ifdef _FOR_DEBUG_
    -(BOOL) respondsToSelector:(SEL)aSelector {
        printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]);
        return [super respondsToSelector:aSelector];
    }
    #endif

    你需要在每个object的.m或者.mm文件中加入上面代码,并且在other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。

     
  • IAP transaction error

    这几天测试IAP时,总是出现下列错误:

    You’ve already purchased this but it hasn’t been downloaded…..

    然后就是,Transaction Failed,错误原因是:无法连接iTune Store。上网查了一下很多人说是iTunes Store的问题,等几天就好了,但我用另一个iDP的账户又没有问题。进过调试,最后发现问题出在iTune Store 的 test account上,原来我没有为新iDP账户创建test account,这原来是个低级错误,不过Apple的错误信息也太容易误导人了吧?

     
  • 怎样处理EXC_BAD_ACCESS

    相信很多人都知道通过NSZombies来帮助调试出现EXC_BAD_ACCESS的情况,但有时还是找不到需要的信息,那么应该怎么办呢?

    下面通过一个例子来说明.下面是hello world的代码:

    1
    2
    3
    NSString* hello = [NSString stringWithFormat:@"Hello world"];
    NSLog(@"What you say is %@",hello);
    [hello release];

    运行后出现EXC_BAD_ACCESS错误.但没有其他任何提示,这时候通过右击executables下的应用程序名,选择get info后,在arguments下输入环境变量(NSZombieEnabled,MallocStackLogging),如图所示:

    add_zombie

    再次运行后程序crash,如图:
    crash

    这次可以看到问题是”message sent to dealloced object”了,但具体是哪个语句引起的还并不知道,于是需要在gdb上输入以下语句:

    shell malloc_history pid address

    那么pid和address是什么呢?再看下crash的图片结合一下我以下使用的命令,你应该很快就可以判定pid和address是从哪里来的了,我的命令是:

    shell malloc_history 596 0×5f3ef80

    再次运行,程序crash时会出现大量的stack trace信息,如下图是与本程序相关的:
    malloc_history

    根据这些信息大家就可以找到问题出现在[BadAccessViewController viewDidLoad] 中与 +[NSString stringWithFormat:] 有关的地方.

    最后大家记得把环境变量NSZombieEnabled,MallocStackLogging删除或设置为NO,因为它们会使得内存不会被释放.

     
  • Xcode不支持iPhoe OS 3.2.1的解决方法

    最近iPad升级到iPhone 3.2.1,今天准备进行真机调试,猛然发现Xcode下出现下列错误:


    The version of iPhone OS on “xxxx” does not match any of the versions of iPhone OS supported for development with this copy of Xcode. Please restore the device to a version of the OS listed below. If necessary, the latest version of Xcode is available here.


    Google 了一下,发现是3.2.1的目录在DeviceSupport下不存在。解决办法是用最接近的OS版本使用ln命令进行链接。不过在操作过程中有两个问题:


    1. 不知什么原因,ln -s 命令后总是为文件而不是目录
    2. 不知OS 3.2的build number


    于是,采用最笨但最为有效的方法:


    在/Developer/Platforms/iPhoneOS.platform/DeviceSupport目录下创建3.2.1目录,然后,将3.2下所有文件及目录复制到3.2.1下,重新启动Xcode,问题解决。

     
  • 都是Backgrounder惹的祸 – 解决“越狱”真机调试的问题

    我的iPhone越狱后,在用Xcode进行调试时出现以下错误信息:


    warning: Unable to read symbols for “/Library/MobileSubstrate/DynamicLibraryies/libstatusbar.dylib” (file not found).

    Program received singal: “SIGUSR1″.


    上网查了一下原来是Backgrounder在作怪,最简单的解决方法就是在Backgournder的overrides设定中,禁止要调试的程序以background模式运行即可。


    想要知道具体原因,请参见:Backgrounder vs. Build and Run

     
  • 调试教程 – 使用UIRecorder Instrument将测试自动化

    (注:这是我以前收集的一篇文章,找不到出处了,稍作修改在此发布)


    如果你发现程序的bug,但每次进行测试都需要许多步骤才能重现问题,那么本教程适合你。通常,测试和调试是非常繁琐的事情,iPhone程序的开发尤其如此。

    读文章 »

     
  • Xcode之宏

    注:宏的使用可以节省代码重复输入工作,还可以为调试带来各种好处。本文列出了几个非常简单实用的宏。
    读文章 »