<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Code Review</title>
	<atom:link href="http://outerlevel.com/blog/2006/12/01/code-review/feed/" rel="self" type="application/rss+xml" />
	<link>http://outerlevel.com/blog/2006/12/01/code-review/</link>
	<description>Building a MicroISV</description>
	<lastBuildDate>Sun, 14 Aug 2011 16:36:12 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
	<item>
		<title>By: Scott Morrison</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-666</link>
		<dc:creator>Scott Morrison</dc:creator>
		<pubDate>Tue, 12 Dec 2006 03:01:41 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-666</guid>
		<description>__FUNCTION__ and __PRETTY_FUNCTION__ are fine and can be used -- they are C niceties and as Obj-C is a superset, they can be used -- just remember they are type const char * 

I use them in debug code to define a basic class with a macro to all the log


As such:


-----MyLog.h
// some loglevels -- your labels would vary
#define MTLogAlways 0
#define MTLogUpdates 1
#define MTLogLibraryUpdates 2
#define MTLogSearches 4

@interface MyLog : NSObject
{
}
+(void)logWithOptions:(int)options file:(char*)sourceFile function:(char*)functionName lineNumber:(int)lineNumber format:(NSString*)format, ...;

#define MyLog(opts,s,...) [MyLog logWithOptions:opts file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__]
@end
-----  MyLog.m
static int __MyLogLevel;

@implementation MyLog
+(void)initialize
{
	__MyLogLevel= [[[NSUserDefaults standardUserDefaults] objectForKey:@&quot;logLevel&quot;] intValue];  
	// you can store logLevel as a hidden preference -- this would be a bitwise and to add logging for different parts of your code.
			
}
+(void)logWithOptions:(int)options file:(char*)sourceFile function:(char*)functionName lineNumber:(int)lineNumber
		format:(NSString*)format, ...{
	
   if(options == 0 &#124;&#124; __MyLogLevel &amp; options ){ 
		NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
		va_list ap;
		NSString *print,*file, *function;
		va_start(ap,format);
		file=[[NSString alloc] initWithBytes:sourceFile 
									  length:strlen(sourceFile) 
									encoding:NSUTF8StringEncoding];
		function = [NSString stringWithCString:functionName];
		print=[[NSString alloc] initWithFormat:format arguments:ap];
		va_end(ap);
		NSLog(@&quot;%@:%d; %@&quot;,function,lineNumber ,print);
		[print release];
		[file release];
		
		[pool release];
		
	}
	return;
}

@end

-----

now to log in code

	MyLog(MTLogAlways,@&quot;Hello %@&quot;,aString);

would output
	x.x.x.x myapp[1234] -[myClass mytestmethod]:5; Hello world
assuming aString was @&quot;world&quot;
	
whereas
	MyLog(MTLogUpdates,@&quot;Hello world&quot;);
would only log if the first bit of the logLevel pref is on.  (ie logLevel &amp; 1 = 1)

Note that I am cleaning this up from my code -- it may not be working 100% but you should get the idea...</description>
		<content:encoded><![CDATA[<p>__FUNCTION__ and __PRETTY_FUNCTION__ are fine and can be used &#8212; they are C niceties and as Obj-C is a superset, they can be used &#8212; just remember they are type const char * </p>
<p>I use them in debug code to define a basic class with a macro to all the log</p>
<p>As such:</p>
<p>&#8212;&#8211;MyLog.h<br />
// some loglevels &#8212; your labels would vary<br />
#define MTLogAlways 0<br />
#define MTLogUpdates 1<br />
#define MTLogLibraryUpdates 2<br />
#define MTLogSearches 4</p>
<p>@interface MyLog : NSObject<br />
{<br />
}<br />
+(void)logWithOptions:(int)options file:(char*)sourceFile function:(char*)functionName lineNumber:(int)lineNumber format:(NSString*)format, &#8230;;</p>
<p>#define MyLog(opts,s,&#8230;) [MyLog logWithOptions:opts file:__FILE__ function: (char *)__FUNCTION__ lineNumber:__LINE__ format:(s),##__VA_ARGS__]<br />
@end<br />
&#8212;&#8211;  MyLog.m<br />
static int __MyLogLevel;</p>
<p>@implementation MyLog<br />
+(void)initialize<br />
{<br />
	__MyLogLevel= [[[NSUserDefaults standardUserDefaults] objectForKey:@&#8221;logLevel&#8221;] intValue];<br />
	// you can store logLevel as a hidden preference &#8212; this would be a bitwise and to add logging for different parts of your code.</p>
<p>}<br />
+(void)logWithOptions:(int)options file:(char*)sourceFile function:(char*)functionName lineNumber:(int)lineNumber<br />
		format:(NSString*)format, &#8230;{</p>
<p>   if(options == 0 || __MyLogLevel &amp; options ){<br />
		NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];<br />
		va_list ap;<br />
		NSString *print,*file, *function;<br />
		va_start(ap,format);<br />
		file=[[NSString alloc] initWithBytes:sourceFile<br />
									  length:strlen(sourceFile)<br />
									encoding:NSUTF8StringEncoding];<br />
		function = [NSString stringWithCString:functionName];<br />
		print=[[NSString alloc] initWithFormat:format arguments:ap];<br />
		va_end(ap);<br />
		NSLog(@&#8221;%@:%d; %@&#8221;,function,lineNumber ,print);<br />
		[print release];<br />
		[file release];</p>
<p>		[pool release];</p>
<p>	}<br />
	return;<br />
}</p>
<p>@end</p>
<p>&#8212;&#8211;</p>
<p>now to log in code</p>
<p>	MyLog(MTLogAlways,@&#8221;Hello %@&#8221;,aString);</p>
<p>would output<br />
	x.x.x.x myapp[1234] -[myClass mytestmethod]:5; Hello world<br />
assuming aString was @&#8221;world&#8221;</p>
<p>whereas<br />
	MyLog(MTLogUpdates,@&#8221;Hello world&#8221;);<br />
would only log if the first bit of the logLevel pref is on.  (ie logLevel &amp; 1 = 1)</p>
<p>Note that I am cleaning this up from my code &#8212; it may not be working 100% but you should get the idea&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Stevenson</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-663</link>
		<dc:creator>Scott Stevenson</dc:creator>
		<pubDate>Tue, 12 Dec 2006 00:34:09 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-663</guid>
		<description>&lt;i&gt;For Cocoa work, Iâ€™m having a harder time stepping away from Xcode&lt;/i&gt;

Google for &#039;textmate objective-c screencast&#039;. I think it might make the difference.</description>
		<content:encoded><![CDATA[<p><i>For Cocoa work, Iâ€™m having a harder time stepping away from Xcode</i></p>
<p>Google for &#8216;textmate objective-c screencast&#8217;. I think it might make the difference.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jon Trainer</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-662</link>
		<dc:creator>Jon Trainer</dc:creator>
		<pubDate>Mon, 11 Dec 2006 21:21:44 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-662</guid>
		<description>Joeroen:  I&#039;m currently using the TextMate demo and trying to give a good honest try.  So far I really like it for HTML work.  I&#039;m using it to author my help documentation for my upcoming release of LicenseKeeper.   For Cocoa work, I&#039;m having a harder time stepping away from Xcode.</description>
		<content:encoded><![CDATA[<p>Joeroen:  I&#8217;m currently using the TextMate demo and trying to give a good honest try.  So far I really like it for HTML work.  I&#8217;m using it to author my help documentation for my upcoming release of LicenseKeeper.   For Cocoa work, I&#8217;m having a harder time stepping away from Xcode.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Outer Level &#187; Blog Archive &#187; Cocoa Blogs</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-661</link>
		<dc:creator>Outer Level &#187; Blog Archive &#187; Cocoa Blogs</dc:creator>
		<pubDate>Mon, 11 Dec 2006 21:16:33 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-661</guid>
		<description>[...] I think this is a great idea and I can&#8217;t believe no one did this before. Scott has also been kind enough to link to my &#8220;Code Review&#8221; article, though he title it &#8220;Learning from Other People&#8217;s Code&#8221;. [...]</description>
		<content:encoded><![CDATA[<p>[...] I think this is a great idea and I can&#8217;t believe no one did this before. Scott has also been kind enough to link to my &#8220;Code Review&#8221; article, though he title it &#8220;Learning from Other People&#8217;s Code&#8221;. [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jeroen Leenarts</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-660</link>
		<dc:creator>Jeroen Leenarts</dc:creator>
		<pubDate>Mon, 11 Dec 2006 21:14:07 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-660</guid>
		<description>It&#039;s a bot offtopic but:

Scott&#039;s entries about TextMate made me give it a sincere trial. Never looked back since.</description>
		<content:encoded><![CDATA[<p>It&#8217;s a bot offtopic but:</p>
<p>Scott&#8217;s entries about TextMate made me give it a sincere trial. Never looked back since.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Stevenson</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-657</link>
		<dc:creator>Scott Stevenson</dc:creator>
		<pubDate>Sat, 02 Dec 2006 23:43:43 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-657</guid>
		<description>&lt;i&gt;You are quite the TextMate pusher lately&lt;/i&gt;

I wasn&#039;t until I realized most Mac programmers didn&#039;t even know what it did.</description>
		<content:encoded><![CDATA[<p><i>You are quite the TextMate pusher lately</i></p>
<p>I wasn&#8217;t until I realized most Mac programmers didn&#8217;t even know what it did.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jon Trainer</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-656</link>
		<dc:creator>Jon Trainer</dc:creator>
		<pubDate>Sat, 02 Dec 2006 13:33:19 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-656</guid>
		<description>Thanks Scott.  &quot;Hidden&quot; does makes me feel a bit better.

You are quite the TextMate pusher lately.  I&#039;ll have to download it and give it a try.</description>
		<content:encoded><![CDATA[<p>Thanks Scott.  &#8220;Hidden&#8221; does makes me feel a bit better.</p>
<p>You are quite the TextMate pusher lately.  I&#8217;ll have to download it and give it a try.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Stevenson</title>
		<link>http://outerlevel.com/blog/2006/12/01/code-review/comment-page-1/#comment-655</link>
		<dc:creator>Scott Stevenson</dc:creator>
		<pubDate>Sat, 02 Dec 2006 11:48:39 +0000</pubDate>
		<guid isPermaLink="false">http://outerlevel.com/blog/2006/12/01/code-review/#comment-655</guid>
		<description>The _cmd variable is documented under &lt;a href=&quot;http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_6.html#//apple_ref/doc/uid/TP30001163-CH7-TPXREF134&quot; rel=&quot;nofollow&quot;&gt;Hidden Arguments&lt;/a&gt;. The word &quot;hidden&quot; is right in the name so don&#039;t feel bad.

TextMate&#039;s &#039;log&#039; tab trigger fills this in automatically for you.</description>
		<content:encoded><![CDATA[<p>The _cmd variable is documented under <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_6.html#//apple_ref/doc/uid/TP30001163-CH7-TPXREF134" rel="nofollow">Hidden Arguments</a>. The word &#8220;hidden&#8221; is right in the name so don&#8217;t feel bad.</p>
<p>TextMate&#8217;s &#8216;log&#8217; tab trigger fills this in automatically for you.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

