<?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>Vincent Gable's Blog &#187; NSLog</title>
	<atom:link href="http://vgable.com/blog/tag/nslog/feed/" rel="self" type="application/rss+xml" />
	<link>http://vgable.com/blog</link>
	<description>my weblog.</description>
	<lastBuildDate>Tue, 29 Nov 2011 22:20:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The Most Useful Objective-C Code I&#8217;ve Ever Written</title>
		<link>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/</link>
		<comments>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 10:01:01 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Bug Bite]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[LOG_EXPR]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[NSLog]]></category>
		<category><![CDATA[Preprocessor]]></category>
		<category><![CDATA[printf]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=670</guid>
		<description><![CDATA[Actually, it&#8217;s the most useful code I&#8217;ve extended; credit for the core idea goes to Dave Dribin with his Handy NSString Conversion Macro. LOG_EXPR(x) is a macro that prints out x, no matter what type x is, without having to worry about format-strings (and related crashes from eg. printing a C-string the same way as [...]]]></description>
			<content:encoded><![CDATA[<p>Actually, it&#8217;s the most useful code I&#8217;ve <em>extended</em>; credit for the core idea goes to <a href="http://www.dribin.org/dave/">Dave Dribin</a> with his <a href="http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/"><cite>Handy NSString Conversion Macro</cite></a>.</p>
<p><strong><code><a href="">LOG_EXPR</a>(x)</code> is a macro that prints out <code>x</code>, no matter what type <code>x</code> is</strong>, without having to worry about format-strings (and related crashes from eg. printing a C-string the same way as an <code>NSString</code>). It works on Mac OS X and iOS. Here are some examples,</p>
<p><code>LOG_EXPR(self.window.screen);</code></p>
<blockquote><p>self.window.screen = &lt;UIScreen: 0x6d20780; bounds = {{0, 0}, {320, 480}}; mode = &lt;UIScreenMode: 0x6d20c50; size = 320.000000 x 480.000000&gt;&gt;
</p></blockquote>
<p><code>LOG_EXPR(self.tabBarController.viewControllers);</code></p>
<blockquote><p>self.tabBarController.viewControllers = (<br />
    &#8220;&lt;UINavigationController: 0xcd02e00&gt;&#8221;,<br />
    &#8220;&lt;SavingsViewController: 0xcd05c40&gt;&#8221;,<br />
    &#8220;&lt;SettingsViewController: 0xcd05e90&gt;&#8221;<br />
)</p></blockquote>
<p>Pretty straightforward, really. The biggest convenience so far is having the expression printed out, so you don&#8217;t have to write out a name redundantly in the format string (eg. <code> NSLog(@"actionURL = %@", actionURL)</code>). But <code>LOG_EXPR</code> really shows it&#8217;s worth when you start using scalar or <code>struct</code> expressions:</p>
<p><code>LOG_EXPR(self.window.windowLevel);</code></p>
<blockquote><p>self.window.windowLevel = 0.000000</p></blockquote>
<p><code>LOG_EXPR(self.window.frame.size);</code></p>
<blockquote><p>self.window.frame.size = {320, 480}</p></blockquote>
<p>Yes, there are expressions that won&#8217;t work, but they&#8217;re pretty rare for me. I use <code>LOG_EXPR</code> every day. Several times. It&#8217;s not quite as good as having <a href="http://vgable.com/blog/2010/06/14/ask-f-script/">a REPL for Cocoa</a>, but it&#8217;s handy.</p>
<p><a href="#Get_LOG_EXPR">Give it a try</a>.</p>
<h3>How It Works</h3>
<p>The problem is how to pick a function or format string to print <code>x</code>, based on the type of <code>x</code>. C++&#8217;s type-based dispatch would be a good fit here, but it&#8217;s verbose (a full function-definition per type) and I wanted to use pure Objective-C if possible. Fortunately, <strong>Objective-C has an <a href="http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html"><code>@encode()</code></a>  compiler directive that returns a string describing any type it&#8217;s given.</strong> Unfortunately it works on <em>types</em>, not variables, but with C99 <strong>the <code><a href="http://gcc.gnu.org/onlinedocs/gcc/Typeof.html">typeof()</a></code> compiler directive lets us get the type of any variable</strong>, which we can pass to <code>@encode()</code>.  The final bit of compiler magic is using <a href="http://gcc.gnu.org/onlinedocs/cpp/Stringification.html">stringification (<code>#</code>)</a> to print out the literal string inside <code>LOG_EXPR()</code>&#8216;s parenthesis.</p>
<h3>The Macro, Line By Line</h3>
<div class="code-box">
<pre>
1 #define LOG_EXPR(_X_) do{\
2 	__typeof__(_X_) _Y_ = (_X_);\
3 	const char * _TYPE_CODE_ = @encode(__typeof__(_X_));\
4 	NSString *_STR_ = VTPG_DDToStringFromTypeAndValue(_TYPE_CODE_, &#038;_Y_);\
5 	if(_STR_)\
6 		NSLog(@"%s = %@", #_X_, _STR_);\
7 	else\
8 		NSLog(@"Unknown _TYPE_CODE_: %s for expression %s in function %s, file %s, line %d", _TYPE_CODE_, #_X_, __func__, __FILE__, __LINE__);\
9 }while(0)
</pre>
</div>
<ol>
<li>The first and last lines are a way to put <code>{}</code>&#8216;s around the macro to prevent <a href="http://en.wikipedia.org/wiki/C_preprocessor#Multiple_statements">unintended effects</a>. The <code>do{}while(0);</code> &#8220;loop&#8221; does nothing else.</li>
<li>First evaluate the expression, <code>_X_</code>, given to <code>LOG_EXPR</code> <em>once</em>, and store the result in a <code>_Y_</code>. We need to use <code><a href="http://gcc.gnu.org/onlinedocs/gcc/Typeof.html">typeof()</a></code> (which had to be written <code>__typeof__()</code> to appease some versions of GCC) to figure out the type of <code>_Y_</code>.</li>
<li><code>_TYPE_CODE_</code> is c-string that <a href="http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html">describes the type</a> of the expression we want to print out.</li>
<li>Now we have enough information to call a function, <code>VTPG_DDToStringFromTypeAndValue()</code> to convert the expression&#8217;s value to a string. We pass it the <code>_TYPE_CODE_</code> string, and <em>the address of </em> <code>_Y_</code>, which is a pointer, and has a known size. We can&#8217;t pass <code>_Y_</code> directly, because depending on what <code>_X_</code> is, it will have different types and could be of any size.</li>
<li><code>VTPG_DDToStringFromTypeAndValue()</code> returns <code>nil</code> if it can&#8217;t figure out how to convert a value to a string.</li>
<li>Everything went well, print the <a href="http://gcc.gnu.org/onlinedocs/cpp/Stringification.html">stringified</a> expression, <code>#_X_</code>, and  the string representing it&#8217;s value, <code>_STR_</code>.</li>
<li>otherwise…</li>
<li>The expression had a type we can&#8217;t handle, print out a verbose diagnostic message.</li>
<li>See line 1.</li>
</ol>
<h3>The <code>VTPG_DDToStringFromTypeAndValue()</code> Function</h3>
<p>See the source in <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m">VTPG_Common.m</a>:</p>
<p><iframe src ="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m" width="100%" height="300">(Your browser does not support iframes.)</iframe></p>
<p>It&#8217;s derived from  <a href="http://www.dribin.org/dave/">Dave Dribin</a>&#8216;s function <a href="http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/"> <code>DDToStringFromTypeAndValue()</code></a>, and is pretty straightforward: <code>strcmp()</code> the type-string, and if it matches a known type call a function, or use <code>+[NSString stringWithFormat]:</code>, to turn the value into a string.</p>
<h3>The First Step Twords Fixing Your Macro Problem is Admitting it&#8230;</h3>
<p>So yeah, maybe I went a little wild with macros here…</p>
<p>But it took out some <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">WET</a>-ness of the original code, and prevents me from accidentally mixing up types in a long wall of <code>if</code>s, eg.</p>
<div class="code-box">
<pre>
else if (strcmp(typeCode, @encode(NSRect)) == 0)
{
    return NSStringFromRect(*(NSRange *)value);
}
else if (strcmp(typeCode, @encode(NSRange)) == 0)
{
    return NSStringFromRect(*(NSRange *)value);
}
</pre>
</div>
<p>If I were cool, I&#8217;d use <code>NSDictionary</code>s to map from the <code>@encode</code>-string to an appropriate format string or function pointer.  This is conceptually cleaner; less error-prone than using macros; and almost certainly faster. Unfortunately, it gets a little tricky with functions, since I need to deference <code>value</code> into the proper type.</p>
<p>One final note from my testing, I could do away with the <code>strcmp()</code>s, because directly comparing <code>@encode</code> string pointers (eg <code>if(typeCode == @encode(NSString*))</code> works. I don&#8217;t know if it will <em>always</em> work though, so relying on it strikes me as a profoundly Bad Idea. But maybe that bad idea will give someone a good idea.</p>
<h3>Limitations</h3>
<h4>Arrays</h4>
<p>C arrays generally muck things up. Casting to a pointer works around this:</p>
<div class="code-box">
<pre>
char x[14] = "Hello, world!";
//LOG_EXPR(x); //error: invalid initializer
LOG_EXPR((char*)x); //prints fine
</pre>
</div>
<h4><code>__func__</code></h4>
<p>Because it is a <code>static const char []</code>, <code><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1642.html">__func__</a></code> (and <code>__FUNCTION__</code> or <code>__PRETTY_FUNCTION__</code>) need casting to <code>char*</code> to work with <code>LOG_EXPR</code>. Because logging out a function/method call is something I do frequently, I use the macro:</p>
<div class="code-box">
<pre>
#define LOG_FUNCTION()	NSLog(@"%s", __func__)</pre>
</div>
<h4><code>long double</code> (Leopard and older)</h4>
<p>On older systems, <code>LOG_EXPR</code> won&#8217;t work with a <code>long double</code> value, because <code>@encode(long double)</code> gives the same result as <code>@encode(double)</code>. This is a <a href="http://openradar.appspot.com/6468314">known issue</a> with the runtime. The top-level <code>LOG_EXPR</code> macro could detect a <code>long double</code> with <code>if((sizeof(_X_) == sizeof(long double)) &#038;&#038; (_TYPE_CODE_ == @encode(double)))</code>. But I doubt this will ever be necessary.</p>
<p>I haven&#8217;t actually written any code that uses <code>long double</code>, because I <strong>use <code><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/doc/uid/20000055-BCIHCEFJ">NSDecimal</a></code>, or another base-10 number format, for situations that require more precision than a <code>double</code>.</strong></p>
<h3>Scaling and Frameworks </h3>
<p>Growing <code>LOG_EXPR</code> to handle <em>every</em> type is a lot of work. I&#8217;ve only added types that I&#8217;ve actually needed to print. This has kept the code manageable, and seems to be working so far.</p>
<p>The biggest problem I have is <strong>how to deal with types that are in frameworks that not every project includes</strong>. Projects that use CoreLocation.framework need to be able to use <code>LOG_EXPR</code> to print out CoreLocation specific <code>struct</code>s, like <code> CLLocationCoordinate2D</code>. But projects that <em>don&#8217;t</em> use CoreLocation.framework don&#8217;t have a definition of the <code>CLLocationCoordinate2D</code> type, so code to convert it to a string won&#8217;t compile. There are two ways I&#8217;ve tried to solve the problem</p>
<h4>Comment-out framework-specific code</h4>
<p>This is pretty self-explanatory, I&#8217;ll fork VTPG_Common.m and un-comment-out code for types that my project needs to print. It works, but it&#8217;s drudgery. Programmers hate that.</p>
<h4>Hardcode type info</h4>
<p>The idea is to hard-code the string that <code>@encode(SomeType)</code> would evaluate to, and then (since we know how <code>SomeType</code> is laid out in memory) use casting and pointer-arithmetic to get at the fields.</p>
<p>For example:</p>
<div class="code-box">
<pre>
//This is a hack to print out CLLocationCoordinate2D, without needing to #import &lt;CoreLocation/CoreLocation.h&gt;
//A CLLocationCoordinate2D is a struct made up of 2 doubles.
//We detect it by hard-coding the result of @encode(CLLocationCoordinate2D).
//We get at the fields by treating it like an array of doubles, which it is identical to in memory.
if(strcmp(typeCode, "{?=dd}")==0)//@encode(CLLocationCoordinate2D)
	return [NSString stringWithFormat:@"{latitude=%g,longitude=%g}",((double*)value)[0],((double*)value)[1]];
</pre>
</div>
<p>This Just Works in a project that includes CoreLocation, and doesn&#8217;t mess up projects that don&#8217;t. Unfortunately it&#8217;s <em>horribly brittle</em>. Any Xcode or system update could break it. It&#8217;s not a tenable fix.</p>
<h3>Areas for Improvement</h3>
<p>If there&#8217;s some type <code>LOG_EXPR</code> can&#8217;t handle that you need, please <a href="http://github.com/VTPG/CommonCode">jump right in and improve it</a>!</p>
<p>When I have time, I plan to write a general parser for <code>@encode()</code>-strings. This will let me print out <em>any</em> <code>struct</code>, which mostly solves the type-defined-in-missing-framework problem, and would let <code>LOG_EXPR</code> Just Work with types from all kinds of POSIX/C libraries.</p>
<h3><a name="Get_LOG_EXPR"></a>Using <code>LOG_EXPR()</code> in Your Project </h3>
<p>Download <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m">VTPG_Common.m</a> and <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.h">VTPG_Common.h</a> from <a href="http://github.com/VTPG/CommonCode">my github repository</a>, and add them to your Xcode project.</p>
<p>Now just add the line <code>#import "VTPG_Common.h"</code> to your prefix file (named <code>&lt;ProjectName&gt;_Prefix.pch</code> by default), after the <code>#ifdef __OBJC__</code>, for example:</p>
<div class="code-box">
<pre>
#ifdef __OBJC__
    #import &lt;Foundation/Foundation.h&gt;
    // maybe other files, depending on project  template...
    #import "VTPG_Common.h"
#endif</pre>
</div>
<p>Now <code>LOG_EXPR()</code> will work everywhere in your project.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>How To Put a % in an NSString/NSLog/printf</title>
		<link>http://vgable.com/blog/2008/11/24/how-to-put-a-in-an-nsstringnslogprintf/</link>
		<comments>http://vgable.com/blog/2008/11/24/how-to-put-a-in-an-nsstringnslogprintf/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 01:01:15 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Foundation]]></category>
		<category><![CDATA[GCC]]></category>
		<category><![CDATA[NSLog]]></category>
		<category><![CDATA[NSString]]></category>
		<category><![CDATA[printf]]></category>
		<category><![CDATA[scanf]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/11/24/how-to-put-a-in-an-nsstringnslogprintf/</guid>
		<description><![CDATA[%% is turned into a single % in a call to NSLog, or -[NSString stringWithFormat:], or the printf-family of functions. Note that %%format will become %format, even if %format usually prints an argument. For example, the code NSLog(@"%%a will print a float in a machine-readable format, so that *scanf can read it back in from [...]]]></description>
			<content:encoded><![CDATA[<p><code>%%</code> is turned into a single <code>%</code> in a call to <code>NSLog</code>, or <code>-[NSString stringWithFormat:]</code>, or the <code>printf</code>-family of functions.</p>
<p>Note that <code>%%<em>format</em></code> will become <code>%<em>format</em></code>, even if <code>%<em>format</em></code> usually prints an argument.  For example, the code</p>
<p><code>NSLog(@"%%a will print a float in a machine-readable format, so that *scanf can read it back in from a string with no loss of precision.", 1.0f);<br /></code></p>
<p>prints:</p>
<blockquote><p>%a will print a float in a machine-readable format, so that *scanf can read<br />
it back in from a string with no loss of precision.</p></blockquote>
<p><em>not</em>:</p>
<blockquote><p>%0x1p+0 will print a float in a machine-readable format, so that *scanf can read it back in from a string with no loss of precision.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/11/24/how-to-put-a-in-an-nsstringnslogprintf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CFShow is NSLog for Core Foundation Types</title>
		<link>http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/</link>
		<comments>http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 00:44:52 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[CoreFoundation]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[NSCFType]]></category>
		<category><![CDATA[NSLog]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/</guid>
		<description><![CDATA[CFShow(coreFoundationThingy) will print out a description of coreFoundationThingy to the console. Output looks something like: {value = w:1186.000000 h:687.000000 type = kAXValueCGSizeType} If NSLog() is printing something out as an NSCFType, try CFShow().]]></description>
			<content:encoded><![CDATA[<p><code>CFShow(coreFoundationThingy)</code> will print out a description of <code>coreFoundationThingy</code> to the console.  Output looks something like:</p>
<blockquote><p><AXValue 0x159f20> {value = w:1186.000000 h:687.000000 type = kAXValueCGSizeType}</p></blockquote>
<p>If <code>NSLog()</code> is printing something out as an <code>NSCFType</code>, try <code>CFShow()</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>-description, Little-Known Hero of Debugging</title>
		<link>http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/</link>
		<comments>http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 00:50:33 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[NSLog]]></category>
		<category><![CDATA[NSObject]]></category>
		<category><![CDATA[NSString]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/</guid>
		<description><![CDATA[Or: How to Make NSLog() Useful With Your Objects Say you have an archaically named NSArray that you want to inspect &#8212; it&#8217;s easy to do, since NSLog(@"The bestiary is %@", bestiary); prints out the array&#8217;s contents 2008-09-16 19:46:06.445 Tester[2678:10b] The bestiary is ( Cheetah, Pumpa, Jaguar, Panther, Tiger, Leopard ) But if you try [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Or: How to Make <code>NSLog()</code> Useful With Your Objects</strong></p>
<p>Say you have an archaically named <code>NSArray</code> that you want to inspect &#8212; it&#8217;s easy to do, since <code>NSLog(@"The bestiary is %@", bestiary);</code> prints out the array&#8217;s contents</p>
<blockquote><p>2008-09-16 19:46:06.445 Tester[2678:10b] The bestiary is (<br />
    Cheetah,<br />
    Pumpa,<br />
    Jaguar,<br />
    Panther,<br />
    Tiger,<br />
    Leopard<br />
)
</p></blockquote>
<p>But if you try to <code>NSLog</code> your own object, you get pretty useless output, like<br />
<blockquote>myObject = &lt;MyObject: 0x53f330&gt;</p></blockquote>
<p>Fortunately, it&#8217;s easy to fix!  Just implement the method <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/description"><code>-(NSString*) description;</code></a> and whatever it returns will be printed by <code>NSLog</code> and GDB (<code>po <em>object</em></code>, will print <em>object</em> in GDB and the Xcode debugging console).</p>
<p>Here&#8217;s an (unfortunately complex) example,<br />
<br /><code>- (NSString*) description;<br />
{<br />
&nbsp;&nbsp;return [NSString stringWithFormat:@"<%@ %p> = {\n\tquestion=%@,\n\tanswer=%@,\n\tsource=%@\n}", [self className], self, self.question, self.answer, self.source];<br />
}<br /></code><br />
output:</p>
<blockquote><p>myObject = &lt;MyObject 0x53eed0&gt; = {<br />
&nbsp;&nbsp;question=What is the Best Thing Ever Of All Times, Ever?,<br />
&nbsp;&nbsp;answer=The Internet!,<br />
&nbsp;&nbsp;source=http://www.cabel.name/2008/01/2007-cabel-yay-awards.html<br />
}</p></blockquote>
<p><strong>Useful Formatters and such</strong></p>
<p><a href="http://vgable.com/blog/2008/08/05/simpler-logging-2/">These macros have made my debugging-life easer</a>.</p>
<p><code>%p</code> tells <code>NSLog</code> to print the address of a pointer.</p>
<p><code>-className</code> returns gives the name of a class as an <code>NSString</code>.</p>
<p><em>Don&#8217;t manually print out a Cocoa <code>struct</code>, ever</em>, there are already <code>NSStringTo*</code> functions to do that for you, like <code>NSStringFromPoint()</code>.</p>
<p><code>NSStringFromSelector()</code> works as advertized (and paired with <code>NSSelectorFromString()</code> is very useful in general).</p>
<p><code>%lld</code> tells <code>NSLog</code> to print a <code>long long</code> (64-bit integer).  See also, <a href="http://www.cplusplus.com/reference/clibrary/cstdio/printf.html"><code>printf</code> reference</a>.</p>
<p><code>%Lf</code> tells <code>NSLog</code> to print a <code>long double</code>. See also, <a href="http://www.cplusplus.com/reference/clibrary/cstdio/printf.html"><code>printf</code> reference</a>.</p>
<p><strong>Best Practices</strong></p>
<p>Whenever you make a new object, I <em>strongly</em> recommended immediately implementing a <code>description</code> method, and religiously keeping it up to date (it&#8217;s not hard, honest!).  This won&#8217;t fix bugs, but it will make finding some of them <em>much easier</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplified Logging</title>
		<link>http://vgable.com/blog/2008/08/05/simpler-logging-2/</link>
		<comments>http://vgable.com/blog/2008/08/05/simpler-logging-2/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 04:44:37 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[NSLog]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/08/05/simpler-logging-2/</guid>
		<description><![CDATA[I have noticed a pattern in my Cocoa code, which I have been able to simplify. I often print out the value of a variable for debugging. 99 times out of 100, the code looks like this: NSLog(@"actionURL = %@", actionURL);, where actionURL is some variable. But using the macros, I can say LOG_ID(actionURL);. This [...]]]></description>
			<content:encoded><![CDATA[<p>I have noticed a pattern in my Cocoa code, which I have been able to simplify.  I often print out the value of a variable for debugging.  99 times out of 100, the code looks like this: <code>NSLog(@"actionURL = %@", actionURL);</code>, where <code>actionURL</code> is some variable.</p>
<p>But using the macros, I can say <b><code>LOG_ID(actionURL);</code></b>.  This is <em>shorter</em>, and <em>non-repetitive</em>.</p>
<p><strong>The macros I use to simplify debugging (2008-09-16):</strong><br />
<code><br />
#define FourCharCode2NSString(err)	NSFileTypeForHFSTypeCode(err)</p>
<p>#define LOG_4CC(x)		NSLog(@"%s = %@", # x, FourCharCode2NSString(x))<br />
#define LOG_FUNCTION()	NSLog(@"%s", __FUNCTION__)<br />
#define LOG_ID(o)		NSLog(@"%s = %@", # o, o)<br />
#define LOG_INT(i)		NSLog(@"%s = %d", # i, i)<br />
#define LOG_INT64(ll)   NSLog(@"%s = %lld", # ll, ll)<br />
#define LOG_FLOAT(f)	NSLog(@"%s = %f", # f, f)<br />
#define LOG_LONG_FLOAT(f) NSLog(@"%s = %Lf", # f, f)<br />
#define LOG_OBJECT(o)	LOG_ID(o)<br />
#define LOG_POINT(p)	NSLog(@"%s = %@", # p, NSStringFromPoint(p))<br />
#define LOG_RECT(r)		NSLog(@"%s = %@", # r, NSStringFromRect(r))<br />
#define LOG_SIZE(s)		NSLog(@"%s = %@", # s, NSStringFromSize(s))</code></p>
<p>Look in <code>assert.h</code> for insight on how to roll your own debugging macros.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/08/05/simpler-logging-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

