<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>iPhoneGeek 爱疯极客 &#187; 调试</title>
	<atom:link href="http://www.iphone-geek.cn/tag/%e8%b0%83%e8%af%95/feed" rel="self" type="application/rss+xml" />
	<link>http://www.iphone-geek.cn</link>
	<description>iPhone 新闻，编程，技巧与提示，代码，教程</description>
	<lastBuildDate>Sun, 25 Jul 2010 13:49:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>调试教程 – 使用UIRecorder Instrument将测试自动化</title>
		<link>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b0%83%e8%af%95%e6%95%99%e7%a8%8b-%e2%80%93-%e4%bd%bf%e7%94%a8uirecorder-instrument%e5%b0%86%e6%b5%8b%e8%af%95%e8%87%aa%e5%8a%a8%e5%8c%96</link>
		<comments>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b0%83%e8%af%95%e6%95%99%e7%a8%8b-%e2%80%93-%e4%bd%bf%e7%94%a8uirecorder-instrument%e5%b0%86%e6%b5%8b%e8%af%95%e8%87%aa%e5%8a%a8%e5%8c%96#comments</comments>
		<pubDate>Mon, 19 Jul 2010 01:52:31 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[基础]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[调试]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=970</guid>
		<description><![CDATA[（注：这是我以前收集的一篇文章，找不到出处了，稍作修改在此发布）

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

比如说，你有个程序需要经过5个步骤才能到达另一个view。如果你有一个bug发生在这个需要5步之多的view上，通常情况下调试的步骤如下：

运行程序
触击 view 1
触击view 2
触击 view 3
触击 view 4
触击 view 5
(程序崩溃)
修改代码
重复以上步骤


如你所见，这是多么痛苦的事情啊。 Kendall Gelner 在 360iDev 上有关使用Instruments 和 XCode进行调试的若干提示的演讲中，对我而言最为有用的就是将测试自动化。我演示一下应该怎么做:
1. 打开希望测试/调试的程序
2. 在模拟器中运行
3. 打开Instrument – 位于 /Developer/Applications/Instruments
 
 



 
4. 选择 UIRecorder 并按Choose - 你将看到下面窗口


 
5.  然后需要将此工具与iPhone模拟器进程链接。按下下拉菜单选择 Default Target -&#62; Attach to Process -&#62; iPhone Simulator.


6. 再按下 Drive &#38; Record 并在模拟器中完成测试所需的所有步骤。至此，UI Recorder记录下了你的一举一动。完成时，按下Stop按钮。 注意： 在完成记录后请不要移动模拟器，因为这有可能会使弄乱整个处理过程。
7. 修改你的代码…
8. 按下 Drive &#38; Record [...]]]></description>
			<content:encoded><![CDATA[<p>（注：这是我以前收集的一篇文章，找不到出处了，稍作修改在此发布）</p>
<p><br class="spacer_" /></p>
<p>如果你发现程序的bug，但每次进行测试都需要许多步骤才能重现问题，那么本教程适合你。通常，测试和调试是非常繁琐的事情，iPhone程序的开发尤其如此。</p>
<p><span id="more-970"></span><br class="spacer_" /></p>
<p>比如说，你有个程序需要经过5个步骤才能到达另一个view。如果你有一个bug发生在这个需要5步之多的view上，通常情况下调试的步骤如下：</p>
<ul>
<li>运行程序</li>
<li>触击 view 1</li>
<li>触击view 2</li>
<li>触击 view 3</li>
<li>触击 view 4</li>
<li>触击 view 5</li>
<li>(程序崩溃)</li>
<li>修改代码</li>
<li>重复以上步骤</li>
</ul>
<p><br class="spacer_" /></p>
<p>如你所见，这是多么痛苦的事情啊。 <a href="http://twitter.com/kendalldevdiary">Kendall Gelner</a> 在 <a href="http://www.360idev.com/">360iDev</a> 上有关使用Instruments 和 XCode进行调试的若干提示的演讲中，对我而言最为有用的就是将测试自动化。我演示一下应该怎么做:</p>
<p style="padding-left: 30px;">1. 打开希望测试/调试的程序</p>
<p style="padding-left: 30px;">2. 在模拟器中运行</p>
<p style="padding-left: 30px;">3. 打开<strong>Instrument</strong> – 位于 /Developer/<a id="KonaLink2" style="position: static; text-decoration: underline !important;" onclick="adlinkMouseClick(event,this,2);" onmouseover="adlinkMouseOver(event,this,2);" onmouseout="adlinkMouseOut(event,this,2);" href="http://www.iphone-geek.cn/wp-admin/#" target="_new"><span style="position: static; color: #346200 !important; font-weight: 400;"><span style="position: static; font-family: Helvetica, Arial, sans-serif; color: #346200 !important; font-weight: 400;">Applications</span></span></a>/Instruments</p>
<ol> </ol>
<ol> </ol>
<p><br class="spacer_" /></p>
<p style="text-align: center;"><strong><a href="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_01.png"><img class="aligncenter" style="zoom: 1; display: inline;" title="screenshot_01" src="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_01-300x229.png" alt="screenshot_01" width="300" height="229" /></a></strong></p>
<p style="text-align: center;"><strong><br />
 </strong></p>
<p style="padding-left: 30px;">4. 选择 <strong>UIRecorder</strong> 并按<strong>Choose </strong>- 你将看到下面窗口</p>
<p style="text-align: center;"><strong><a href="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_02.png"><img class="aligncenter" style="zoom: 1; display: inline;" title="screenshot_02" src="http://icodeblog.com/wp-content/uploads/2009/10/screenshot_02-300x211.png" alt="screenshot_02" width="300" height="211" /></a></strong></p>
<p style="text-align: center;"><strong><br />
 </strong></p>
<p style="padding-left: 30px;">5.  然后需要将此工具与iPhone模拟器进程链接。按下下拉菜单选择 <strong>Default Target</strong> -&gt; <strong>Attach to Process </strong>-&gt; <strong>iPhone Simulator</strong>.</p>
<p style="text-align: center;"><a href="http://icodeblog.com/wp-content/uploads/2009/10/ss_03.png"><img class="aligncenter" style="zoom: 1; display: inline;" title="ss_03" src="http://icodeblog.com/wp-content/uploads/2009/10/ss_03-300x136.png" alt="ss_03" width="300" height="136" /></a></p>
<p><br class="spacer_" /></p>
<p style="padding-left: 30px;">6. 再按下 <strong>Drive &amp; Record</strong> 并在模拟器中完成测试所需的所有步骤。至此，UI Recorder记录下了你的一举一动。完成时，按下<strong>Stop</strong>按钮。 <span style="color: #ff0000;"><strong>注意：</strong></span> 在完成记录后请不要移动模拟器，因为这有可能会使弄乱整个处理过程。</p>
<p style="padding-left: 30px;">7. 修改你的代码…</p>
<p style="padding-left: 30px;">8. 按下 <strong>Drive &amp; Record </strong>按钮亲眼目睹一下有什么神奇的事情发生吧。测试自动进行了！你应该看到它自动模拟了你刚才进行的所有动作。</p>
<p><br class="spacer_" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e7%bc%96%e7%a8%8b/%e8%b0%83%e8%af%95%e6%95%99%e7%a8%8b-%e2%80%93-%e4%bd%bf%e7%94%a8uirecorder-instrument%e5%b0%86%e6%b5%8b%e8%af%95%e8%87%aa%e5%8a%a8%e5%8c%96/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Xcode之宏</title>
		<link>http://www.iphone-geek.cn/%e6%8a%80%e5%b7%a7%e4%b8%8e%e6%8f%90%e7%a4%ba/xcode%e4%b9%8b%e5%ae%8f</link>
		<comments>http://www.iphone-geek.cn/%e6%8a%80%e5%b7%a7%e4%b8%8e%e6%8f%90%e7%a4%ba/xcode%e4%b9%8b%e5%ae%8f#comments</comments>
		<pubDate>Thu, 12 Nov 2009 04:30:54 +0000</pubDate>
		<dc:creator>bagusflyer</dc:creator>
				<category><![CDATA[技巧与提示]]></category>
		<category><![CDATA[调试]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.iphone-geek.cn/?p=200</guid>
		<description><![CDATA[注：宏的使用可以节省代码重复输入工作，还可以为调试带来各种好处。本文列出了几个非常简单实用的宏。

&#160;
这些是我在Xcode中常用到的宏： 
&#160;
CMLog: 用它来代替NSLog：
1#define CMLog(format, ...) NSLog(@&#34;%s:%@&#34;, __PRETTY_FUNCTION__,[NSString stringWithFormat:format, ## __VA_ARGS__]);
&#160;
它的作用是将调用它的类和方法的名称一起输出到控制台。比如你在MyAppDelegate类的applicationDidFinishLaunching方法中调用它：
1CMLog&#40;@&#34;My iPhone is an %@, v %@&#34;, &#91;&#91;UIDevice currentDevice&#93; model&#93;, &#91;&#91;UIDevice currentDevice&#93; systemVersion&#93;&#41;;
&#160;
控制台将输出：
2009-01-05 10:06:28.957 MyApp15173:20b] -[MyAppDelegate applicationDidFinishLaunching:]:
My iPhone is an iPhone Simulator, v 2.2
&#160;
MARK: 此宏用于输出调用它的类和方法名称。适用于只想知道是否一个方法被调用了。
1#define MARK&#160; &#160; CMLog(@&#34;%s&#34;, __PRETTY_FUNCTION__);
&#160;
START_TIMER和END_TIMER: 用于确定一个方法或一段代码的运行时间：
12#define START_TIMER NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; &#160;
#define END_TIMER(msg) &#160;NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; CMLog([NSString stringWithFormat:@&#34;%@ Time [...]]]></description>
			<content:encoded><![CDATA[<p>注：宏的使用可以节省代码重复输入工作，还可以为调试带来各种好处。本文列出了几个非常简单实用的宏。<br />
<span id="more-200"></span></p>
<p>&nbsp;</p>
<p>这些是我在Xcode中常用到的宏： </p>
<p>&nbsp;</p>
<p><strong>CMLog</strong>: 用它来代替NSLog：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6e371a;">#define CMLog(format, ...) NSLog(@&quot;%s:%@&quot;, __PRETTY_FUNCTION__,[NSString stringWithFormat:format, ## __VA_ARGS__]);</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>它的作用是将调用它的类和方法的名称一起输出到控制台。比如你在<strong>MyAppDelegate</strong>类的<strong>applicationDidFinishLaunching</strong>方法中调用它：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CMLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;My iPhone is an %@, v %@&quot;</span>, <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIDevice currentDevice<span style="color: #002200;">&#93;</span> model<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UIDevice currentDevice<span style="color: #002200;">&#93;</span> systemVersion<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>;</div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>控制台将输出：</p>
<pre>2009-01-05 10:06:28.957 MyApp15173:20b] -[MyAppDelegate applicationDidFinishLaunching:]:
My iPhone is an iPhone Simulator, v 2.2</pre>
<p>&nbsp;</p>
<p><strong>MARK</strong>: 此宏用于输出调用它的类和方法名称。适用于只想知道是否一个方法被调用了。</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6e371a;">#define MARK&nbsp; &nbsp; CMLog(@&quot;%s&quot;, __PRETTY_FUNCTION__);</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p><strong>START_TIMER</strong>和<strong>END_TIMER</strong>: 用于确定一个方法或一段代码的运行时间：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6e371a;">#define START_TIMER NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; &nbsp;</span><br />
<span style="color: #6e371a;">#define END_TIMER(msg) &nbsp;NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; CMLog([NSString stringWithFormat:@&quot;%@ Time = %f&quot;;, msg, stop-start]);</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>将<strong>START_TIMER</strong> 置于需评测的代码段开始处，并将<strong>END_TIMER</strong>置于代码段结束处，你就可获得这段代码的运行时间：</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>loadDataFromURL<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>dataURL &nbsp;<br />
<span style="color: #002200;">&#123;</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; START_TIMER; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/"><span style="color: #400080;">NSData</span></a> <span style="color: #002200;">*</span>data <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self doSomeStuff<span style="color: #002200;">:</span>dataURL<span style="color: #002200;">&#93;</span>; &nbsp; &nbsp;<br />
&nbsp; &nbsp; END_TIMER<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;loadDataFromURL&quot;</span><span style="color: #002200;">&#41;</span>; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #a61390;">return</span> data; &nbsp;<br />
<span style="color: #002200;">&#125;</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>输出为:</p>
<pre>2009-01-05 10:31:37.943 MyApp[15283:20b] -[MyAppDelegate loadDataFromURL:]:
loadDataFromURL Time = 3.636021  </pre>
<p>&nbsp;</p>
<p>将所有这些宏定义整理使用条件标志放在预编译的头文件中。调试时，此标志设为1 ，发布时将其设为0 。</p>
<div class="codecolorer-container objc mac-classic" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6e371a;">#if DEBUG==1 &nbsp;</span><br />
&nbsp; &nbsp; <span style="color: #6e371a;">#define CMLog(format, ...) NSLog(@&quot;%s:%@&quot;;, __PRETTY_FUNCTION__,[NSString stringWithFormat:format, ## __VA_ARGS__]); &nbsp; </span><br />
&nbsp; &nbsp; <span style="color: #6e371a;">#define MARK&nbsp; &nbsp; CMLog(@&quot;%s&quot;;, __PRETTY_FUNCTION__); &nbsp;</span><br />
&nbsp; &nbsp; <span style="color: #6e371a;">#define START_TIMER NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate]; &nbsp;</span><br />
&nbsp; &nbsp; <span style="color: #6e371a;">#define END_TIMER(msg) &nbsp;NSTimeInterval stop = [NSDate timeIntervalSinceReferenceDate]; CMLog([NSString stringWithFormat:@&quot;%@ Time = %f&quot;;, msg, stop-start]); &nbsp;</span><br />
<span style="color: #6e371a;">#else &nbsp;</span><br />
&nbsp; &nbsp; <span style="color: #6e371a;">#define CMLog(format, ...) &nbsp;</span><br />
&nbsp; &nbsp; <span style="color: #6e371a;">#define MARK &nbsp;#define START_TIMER &nbsp;</span><br />
&nbsp; &nbsp; <span style="color: #6e371a;">#define END_TIMER(msg) &nbsp;</span><br />
<span style="color: #6e371a;">#endif</span></div></td></tr></tbody></table></div>
<p>&nbsp;</p>
<p>在<em>Debug</em>目标设定中加入：</p>
<pre>OTHER_CFLAGS = -DDEBUG=1  </pre>
<p>&nbsp;</p>
<p>在<em>Release</em> 目标设定中加入：</p>
<pre>OTHER_CFLAGS = -DDEBUG=0
</pre>
<p>&nbsp;</p>
<h5>
          原文见：<a href="http://blog.coriolis.ch/2009/01/05/macros-for-xcode/" rel="bookmark" title="Permanent Link: Macros for Xcode">Macros for Xcode</a><br />
        </h5>
<pre>&nbsp;        </pre>
]]></content:encoded>
			<wfw:commentRss>http://www.iphone-geek.cn/%e6%8a%80%e5%b7%a7%e4%b8%8e%e6%8f%90%e7%a4%ba/xcode%e4%b9%8b%e5%ae%8f/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
