<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Cocoaphony</title>
	
	<link>http://robnapier.net/blog</link>
	<description>Mac and iPhone, on the brain</description>
	<lastBuildDate>Fri, 06 Aug 2010 14:14:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Cocoaphony" /><feedburner:info uri="cocoaphony" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Pandora’s “Profile” pop-up</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/E5TQ4lDn3SA/pandoras-profile-popup-529</link>
		<comments>http://robnapier.net/blog/pandoras-profile-popup-529#comments</comments>
		<pubDate>Fri, 06 Aug 2010 14:14:58 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[PandoraBoy]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=529</guid>
		<description><![CDATA[Several people have noted that PandoraBoy is displaying a "Profile" window over the player that interferes with the player. This is a notification from Pandora because they've changed their privacy settings (you can now make your profile private, and they want to know if you want that).

This should be a one-time event for existing accounts. I suspect that new accounts will not see it. The solution is to open www.pandora.com in Safari, answer the question, and then re-launch PB.]]></description>
			<content:encoded><![CDATA[<p>Several people have noted that PandoraBoy is displaying a &#8220;Profile&#8221; window over the player that interferes with the player. This is a notification from Pandora because they&#8217;ve changed their privacy settings (you can now make your profile private, and they want to know if you want that).</p>

<p>This should be a one-time event for existing accounts. I suspect that new accounts will not see it. The solution is to open www.pandora.com in Safari, answer the question, and then re-launch PB.</p>

<p>PandoraBoy goes directly to the the mini-player on launch. Pandora doesn&#8217;t code for that since it&#8217;s impossible from the website. So sometimes they make interfaces that are larger than the mini-player without updating the mini-player code to resize. PB doesn&#8217;t resize the window (it doesn&#8217;t know how large it should be). It just relies on the mini-player to do it in Javascript, but in cases like this, the mini-player also doesn&#8217;t know how large the window should be.</p>

<p>BTW, I often am asked why PB doesn&#8217;t make the window resizable for cases like this. The answer is that it doesn&#8217;t help. The mini-player is a flash app, and has a clipping frame independent of the window. So while you can resize the window, the content is still clipped at the border of the flash app. Ah, the wonders of Flash.</p>
<img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/E5TQ4lDn3SA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/pandoras-profile-popup-529/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/pandoras-profile-popup-529</feedburner:origLink></item>
		<item>
		<title>PandoraBoy 0.8.2 – Fixes Flash</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/h4Ya2S7YbIM/pandoraboy-082-fixes-flash-523</link>
		<comments>http://robnapier.net/blog/pandoraboy-082-fixes-flash-523#comments</comments>
		<pubDate>Fri, 16 Jul 2010 03:30:24 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[PandoraBoy]]></category>
		<category><![CDATA[cocoa]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=523</guid>
		<description><![CDATA[For those of you having trouble with Flash 10.1, I&#8217;ve fixed PB to handle it. This moves from the hackish &#8220;dig around in the NetscapePlugin objects and call undocumented methods&#8221; approach to a standard CGEvent based keyboard injection. You can&#8217;t use NSApp&#8217;s sendEvent: to talk to Flash (probably because Flash is not in Cocoa). But [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you having trouble with Flash 10.1, I&#8217;ve fixed PB to handle it. This moves from the hackish &#8220;dig around in the NetscapePlugin objects and call undocumented methods&#8221; approach to a standard CGEvent based keyboard injection. You can&#8217;t use NSApp&#8217;s sendEvent: to talk to Flash (probably because Flash is not in Cocoa). But the following code is a good general purpose &#8220;send me a virtual keystroke.&#8221;
<span id="more-523"></span></p>

<pre><code>- (void)sendKeyPress:(int)keycode withModifier:(int)modifier
{
    ProcessSerialNumber psn;
    GetCurrentProcess(&amp;psn);
    CGEventRef modifierEvent;
    if (modifier != 0)
    {
        modifierEvent = CGEventCreateKeyboardEvent(NULL, modifier, YES);
        CGEventPostToPSN(&amp;psn, modifierEvent);
    }

    CGEventRef keyEvent = CGEventCreateKeyboardEvent(NULL, keycode, YES);
    CGEventPostToPSN(&amp;psn, keyEvent);
    CGEventSetType(keyEvent, kCGEventKeyUp);
    CGEventPostToPSN(&amp;psn, keyEvent);
    CFRelease(keyEvent);

    if (modifier != 0)
    {
        CGEventSetType(modifierEvent, kCGEventKeyUp);
        CGEventPostToPSN(&amp;psn, modifierEvent);
        CFRelease(modifierEvent);
    }
}
</code></pre>

<p>First note the use of <code>CGEventPostToPSN()</code>. I originally made the mistake of using <code>CGEventPost()</code>. The problem is that this will send the keystroke to the currently active application, not PandoraBoy. For keyboard shortcuts and applescript where PB will certainly be in the background, <code>CGEventPostToPSN()</code> is a must here.</p>

<p>Note that this uses virtual keycodes. That&#8217;s fine for PB, since (for now) we only send things that are universal (like spacebar). But it will be a problem when I implement sending &#8220;z&#8221; to snooze a song. The problem is that &#8220;z&#8221; means &#8220;the location of &#8216;z&#8217; on an ANSI keyboard.&#8221; If you have a different keyboard layout, it&#8217;s still going to act like you pressed that lower left-hand key beside the shift, not &#8220;z&#8221;. If people have trouble with this, I&#8217;ll look into UCKeyboardLayout, but it was too much for tonight, and I don&#8217;t need it myself.</p>

<p>The modifiers are tricky because if you want to send &#8220;Z&#8221; that really means &#8220;shift down, z down, z up, shift up.&#8221; This method takes care of all that for you. You would send &#8220;Z&#8221; like this:</p>

<pre><code>[self sendKeyPress:kVK_ANSI_Z withModifier:kVK_Shift];
</code></pre>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Frobnapier.net%2Fblog%2Fpandoraboy-082-fixes-flash-523&amp;linkname=PandoraBoy%200.8.2%20%26%238211%3B%20Fixes%20Flash"><img src="http://robnapier.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p><img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/h4Ya2S7YbIM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/pandoraboy-082-fixes-flash-523/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/pandoraboy-082-fixes-flash-523</feedburner:origLink></item>
		<item>
		<title>Building Address Book plugins</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/ttLCsbAF0OQ/building-address-book-plugins-520</link>
		<comments>http://robnapier.net/blog/building-address-book-plugins-520#comments</comments>
		<pubDate>Thu, 15 Jul 2010 20:17:22 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[cocoa]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=520</guid>
		<description><![CDATA[Just a reminder, because the template doesn&#8217;t seem to set this up correctly. To build an Address Book action plugin for 10.6, you need to compile for x86_64 or it will silently not show up. If you plan to support 10.5, you&#8217;ll need i386 as well. The template seems to build 32-bit universal (i386, ppc) [...]]]></description>
			<content:encoded><![CDATA[<p>Just a reminder, because the template doesn&#8217;t seem to set this up correctly. To build an Address Book action plugin for 10.6, you need to compile for x86_64 or it will silently not show up. If you plan to support 10.5, you&#8217;ll need i386 as well. The template seems to build 32-bit universal (i386, ppc) by default.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Frobnapier.net%2Fblog%2Fbuilding-address-book-plugins-520&amp;linkname=Building%20Address%20Book%20plugins"><img src="http://robnapier.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p><img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/ttLCsbAF0OQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/building-address-book-plugins-520/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/building-address-book-plugins-520</feedburner:origLink></item>
		<item>
		<title>Hijacking with method_exchangeImplementations()</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/OrucEzpd1Z8/hijacking-methodexchangeimplementations-502</link>
		<comments>http://robnapier.net/blog/hijacking-methodexchangeimplementations-502#comments</comments>
		<pubDate>Wed, 07 Jul 2010 22:17:25 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[cocoa]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=502</guid>
		<description><![CDATA[Sometimes you want to inject some logic into a method you don't control. The most common sane reason to do this is for debugging or profiling. For instance, you might want to log every time the various NSNotificationCenter methods are called so you can determine if that's a performance bottleneck. In most OOP languages your only option would be to subclass the object you want to instrument and then arrange for every instance of that object to be your subclass. In many cases that's either very difficult or outright impossible, particularly if the object is used internally by a system framework. But Objective-C is highly dynamic, and message dispatching is resolved at runtime. You can modify how it works using method_exchangeImplementations().]]></description>
			<content:encoded><![CDATA[<p><em>Based on a <a href="http://stackoverflow.com/questions/1929740/is-there-a-way-to-retrieve-every-responder-that-has-handled-a-uitouch">discussion</a> from StackOverflow.</em></p>

<p>Sometimes you want to inject some logic into a method you don&#8217;t control. The most common sane reason to do this is for debugging or profiling. For instance, you might want to log every time the various <code>NSNotificationCenter</code> methods are called so you can determine if that&#8217;s a performance bottleneck. (As I discovered myself, if you have thousands of notification observations in your system, it can be a serious performance problem.)</p>

<p>In most OOP languages your only option would be to subclass the object you want to instrument and then arrange for every instance of that object to be your subclass. In many cases that&#8217;s either very difficult or outright impossible, particularly if the object is used internally by a system framework. But Objective-C is highly dynamic, and message dispatching is resolved at runtime. You can modify how it works.
<span id="more-502"></span></p>

<p>On Mac, there is an <code>NSObject</code> method called <code>poseAsClass:</code> that can achieve this easily. Unfortunately, it&#8217;s deprecated in 10.5 and isn&#8217;t available at all for Mac 64-bit and iPhone. I want a technique that I can use reliably for all my platforms, and luckily there is a fully supported alternative: <code>method_exchangeImplemenations()</code>.</p>

<p>So how do we use it? First, we create a category on our target (NSNotificationCenter):</p>

<pre><code>@interface NSNotificationCenter (RNHijack)
+ (void)hijack;
@end

@implementation NSNotificationCenter (RNHijack)
+ (void)hijackSelector:(SEL)originalSelector withSelector:(SEL)newSelector
{
    Class class = [NSNotificationCenter class];
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method categoryMethod = class_getInstanceMethod(class, newSelector);
    method_exchangeImplementations(originalMethod, categoryMethod);
}

+ (void)hijack
{
    [self hijackSelector:@selector(removeObserver:)
        withSelector:@selector(RNHijack_removeObserver:)];
}

+ (void)RNHijack_removeObserver:(id)notificationObserver
{
    NSLog(@"Removing observer: %@", notificationObserver);
    [self RNHijack_removeObserver:notificationObserver];
}
</code></pre>

<p>Then, somewhere early in my program, I call <code>[NSNotificationCenter hijack]</code>. Now, every <code>removeObserver:</code> message is logged, no matter who sends it, even inside Cocoa itself. To make sure that I catch everything, I often put this in main.m, before the call to &#8216;NSApplicationMain()&#8217;.</p>

<p>The line to pay particular notice to is the apparent infinite loop in <code>RNHijack_removeObserver:</code> that seems to call itself. Why does this work? Because method_exchangeImplementation() <em>swaps</em> the two implementations. The old <code>removeObserver:</code> now points to my implementation, but conversely <code>RNHijack_removeObserver:</code> points to the <em>old</em> implementation.</p>

<p>It is hard to imagine code that is more confusing and fragile than this, which is why this technique must be used with the utmost care. Personally I can&#8217;t imagine using this outside of debugging and profiling. But when you need it, it is an incredibly powerful tool.</p>
<img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/OrucEzpd1Z8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/hijacking-methodexchangeimplementations-502/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/hijacking-methodexchangeimplementations-502</feedburner:origLink></item>
		<item>
		<title>Wrapping C++ – Take 2, Part 2</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/spbiA0nV6XY/wrapping-c-take-2-2-493</link>
		<comments>http://robnapier.net/blog/wrapping-c-take-2-2-493#comments</comments>
		<pubDate>Thu, 10 Jun 2010 05:48:41 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[cocoa]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=493</guid>
		<description><![CDATA[In the <a href="http://robnapier.net/blog/wrapping-c-take-2-1-486">last post</a>, we discussed how to wrap simple C++ objects in Objective-C. But how about more complex objects, particularly with <code>shared_ptr</code>?]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://robnapier.net/blog/wrapping-c-take-2-1-486">last post</a>, we discussed how to wrap simple C++ objects in Objective-C. But how about more complex objects, particularly with <code>shared_ptr</code>?<span id="more-493"></span></p>

<p>Many of the objects I deal with include these, and there are a few special concerns:</p>

<ul>
<li>You can&#8217;t take a <code>shared_ptr</code> to an object during its constructor.</li>
<li>You can&#8217;t easily store a <code>shared_ptr</code> directly in an ivar using the opaque object previously discussed (it relies on a raw pointer to a struct).</li>
</ul>

<p>Consider the following object (slightly abbreviated; a <code>WrapPtr</code> is a <code>shared_ptr&lt;Wrap&gt;</code>):</p>

<pre><code>class WrapListener {
public:
    virtual void onStringDidChange(WrapPtr wrap) = 0;
};

class Wrap : public enable_shared_from_this&lt;Wrap&gt; {
public:
    Wrap(string str) : m_string(str), m_listeners() {};
    string getString() { return m_string; };
    void setString(string str);
    void addListener(WrapListenerPtr listener) { m_listeners.insert(listener); };
    void removeListener(WrapListenerPtr listener) { m_listeners.erase(listener); };
private:
    string m_string;
    WrapListenerWeakSet m_listeners;
};
</code></pre>

<p>This is a very common pattern in the code I work with, but it has a problem for wrapping. If we make the opaque object the listener, there&#8217;s no easy way to call <code>addListener()</code> during the constructor. For example we might be tempted to do this:</p>

<pre><code>struct RNWrapOpaque : public RN::WrapListener,
    public enable_shared_from_this&lt;RNWrapOpaque&gt; {
public:
    RNWrapOpaque(RNWrap *owner, string aStr) : 
    m_owner(owner), wrap(new RN::Wrap(aStr)) {
        wrap-&gt;addListener(shared_from_this());
    };

    ~RNWrapOpaque() {
        wrap-&gt;removeListener(shared_from_this());
    }

    void onStringDidChange(RN::WrapPtr cppWrap) {
        [m_owner.delegate wrapStringDidChange:m_owner];
    }       

    RN::WrapPtr wrap;
private:
    RNWrap *m_owner;
};
</code></pre>

<p>Unfortunately, this will crash. It&#8217;s not possible to call <code>shared_from_this()</code> during a constructor. This can often be solved by adding a <code>Create()</code> method to separate construction from initialization. That&#8217;s a good pattern, but doesn&#8217;t work here because there&#8217;s nowhere to store the <code>shared_ptr</code>. We have to store a raw pointer in the header.</p>

<p>The best solution I believe is to accept that you need a second object for the listener. This actually scales pretty well since the opaque struct may store several objects, and breaking up the different listeners can be better for readability. So that brings us to our example:</p>

<pre><code>class MyWrapListener : public RN::WrapListener {
public:
    MyWrapListener(RNWrap *owner) : m_owner(owner) {};

    void onStringDidChange(RN::WrapPtr cppWrap) {
        [m_owner.delegate wrapStringDidChange:m_owner];
    }   

private:
    RNWrap *m_owner;    
};

struct RNWrapOpaque {
public:
    RNWrapOpaque(RNWrap *owner, string aStr) : 
    wrap(new RN::Wrap(aStr)),
    m_wrapListener(new MyWrapListener(owner)) {
        wrap-&gt;addListener(m_wrapListener);
    };

    ~RNWrapOpaque() {
        wrap-&gt;removeListener(m_wrapListener);
    }

    RN::WrapPtr wrap;
private:
    RN::WrapListenerPtr m_wrapListener;
};

@implementation RNWrap

- (id)initWithString:(NSString *)aString delegate:(id&lt;RNWrapDelegate&gt;)aDelegate {
    self = [super init];
    if (self != nil) {
        self.cpp = new RNWrapOpaque(self, [aString UTF8String]);
        self.delegate = aDelegate;
    }
    return self;
}
</code></pre>

<p>The rest is generally as in the previous article.</p>

<p><a href='http://robnapier.net/blog/wp-content/uploads/2010/06/CppWrap.zip'>CppWrap.zip</a></p>
<img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/spbiA0nV6XY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/wrapping-c-take-2-2-493/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/wrapping-c-take-2-2-493</feedburner:origLink></item>
		<item>
		<title>Wrapping C++ – Take 2, Part 1</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/IcsVGQ-2Ff4/wrapping-c-take-2-1-486</link>
		<comments>http://robnapier.net/blog/wrapping-c-take-2-1-486#comments</comments>
		<pubDate>Wed, 09 Jun 2010 06:39:04 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[cocoa]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=486</guid>
		<description><![CDATA[You have a C++ object that you want to consume in Objective-C. That's easy in ObjC++, but if you make an ivar that references a C++ class, then the header file can only be included by ObjC++ classes. This quickly spreads .mm files throughout your project, creating all kinds of headaches. ObjC is a beautiful thing, and C++ is fine, but ObjC++ is a crazy land that should be carefully segregated from civilized code. So how do we do it?]]></description>
			<content:encoded><![CDATA[<p>Last year, I presented <a href="http://robnapier.net/blog/wrapping-c-objc-20">an approach to wrapping C++</a>. Since then, I&#8217;ve been introduced to other approaches, particularly from gf who helped me better understand opaque objects. Since I do a lot of cross-language work, I&#8217;ve had some opportunity to play with and expand this, and so I&#8217;d like to update my C++ wrapping approach.</p>

<p>First, to remind everyone of the problem: you have a C++ object that you want to consume in Objective-C. That&#8217;s easy in ObjC++, but if you make an ivar that references a C++ class, then the header file can only be included by ObjC++ classes. This quickly spreads .mm files throughout your project, creating all kinds of headaches. ObjC is a beautiful thing, and C++ is fine, but ObjC++ is a crazy land that should be carefully segregated from civilized code. So how do we do it?</p>

<p><span id="more-486"></span>
We create a thin wrapper object to provide an ObjC face on a C++ object. The challenge is how to hide C++ classes from the header file. The answer is to put them in a struct that you forward declare so you don&#8217;t have to expose its contents. Structs are almost identical with C++ classes, but their forward declaration syntax is C-compatible (unlike class). Let&#8217;s look at how this is done.</p>

<p>For this example, we will consider a C++ class called <code>RN::Wrap</code>. It holds a simple string with set and get accessors.</p>

<pre><code>class Wrap {
public:
    Wrap(string str) : m_string(str) {};
    string getString() { return m_string; };
    void setString(string str) { m_string = str; };
private:
    string m_string;
};
</code></pre>

<p>We wrap this into Objective-C++ using an opaque structure, <code>RNWrapOpaque</code>:</p>

<pre><code>struct RNWrapOpaque;
@interface RNWrap : NSObject {
    struct RNWrapOpaque *_cpp;
}
</code></pre>

<p>Since we only include a raw pointer to <code>RNWrapOpaque</code>, we don&#8217;t have to declare anything else about it in the header file. If we tried to store the actual struct here (rather than a pointer), then that would defeat the purpose. This is the only raw pointer we will need.</p>

<p>Since structs are almost identical to classes in C++, we can use class features like constructors and destructors in the implementation (.mm file):</p>

<pre><code>struct RNWrapOpaque {
public:
    RNWrapOpaque(string aStr) : wrap(aStr) {};
    RN::Wrap wrap;
};
</code></pre>

<p>Now initializing and using the opaque object is easy in ObjC++ code:</p>

<pre><code>- (id)initWithString:(NSString *)aString {
    self = [super init];
    if (self != nil) {
        self.cpp = new RNWrapOpaque([aString UTF8String]);
    }
    return self;
}

- (void)dealloc {
    delete _cpp;
    _cpp = NULL;    
    [super dealloc];
}

- (void)setString:(NSString *)aString {
    self.cpp-&gt;wrap.setString([aString UTF8String]);
}

- (NSString *)string {
    return [NSString stringWithUTF8String:
        self.cpp-&gt;wrap.getString().c_str()];
}
</code></pre>

<p>A nice side effect of this usages is that C++ objects are easy to detect through the <code>self.cpp</code> prefix. Memory management is easy since there is only one raw C++ pointer.</p>

<p>Using the class requires no special work. It&#8217;s pure ObjC:</p>

<pre><code>RNWrap *wrap = [[[RNWrap alloc] initWithString:@"my string"] autorelease];
NSLog(@"wrap = %@", [wrap string]);
</code></pre>

<p>In part two, we&#8217;ll discuss how to extend this approach to more complex problems such as smart pointers, listeners/delegates, and bindings.</p>

<p><a href='http://robnapier.net/blog/wp-content/uploads/2010/06/SimpleCppWrap.zip'>SimpleCppWrap.zip</a></p>
<img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/IcsVGQ-2Ff4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/wrapping-c-take-2-1-486/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/wrapping-c-take-2-1-486</feedburner:origLink></item>
		<item>
		<title>Chinese study</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/WxfZM2E38rw/chinese-study-480</link>
		<comments>http://robnapier.net/blog/chinese-study-480#comments</comments>
		<pubDate>Wed, 28 Apr 2010 15:00:57 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[Chinese]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=480</guid>
		<description><![CDATA[Over the years I've travelled to China several times, and now I'm working with large group of developers in Suzhou, Hangzhou and Hefei. A few weeks ago I was able to visit again, and that's gotten me back in the mood to study Chinese. It often helps me to write down things as I learn them, and some of my Chinese coworkers read this blog and might help set me straight as I wander through their language like a bull in a China shop (as it were....) It's a bit off the trail for Cocoa development, so feel free to use the Subscribe2 link on the right to take this category off of your email subscription.]]></description>
			<content:encoded><![CDATA[<p>Over the years I&#8217;ve travelled to China several times, and now I&#8217;m working with large group of developers in Suzhou, Hangzhou and Hefei. A few weeks ago I was able to visit again, and that&#8217;s gotten me back in the mood to study Chinese. It often helps me to write down things as I learn them, and some of my Chinese coworkers read this blog and might help set me straight as I wander through their language like a bull in a China shop (as it were&#8230;.) It&#8217;s a bit off the trail for Cocoa development, so feel free to use the Subscribe2 link on the right to take this category off of your email subscription.<span id="more-480"></span></p>

<p>I&#8217;m currently studying speaking with <a href="http://www.pimsleur.com/Learn-Chinese-Mandarin/Chinese-Mandarin-I-Comprehensive/9780671790615">Pimsleur Chinese Mandarin I Comprehensive</a>. I&#8217;ve found it useful so far, and it seems a good way to learn pronunciation. Of course that can get you in trouble. It is somewhat problematic to learn very well how to say &#8220;I don&#8217;t speak well&#8221; (我说的不好). It gives the impression you are being modest, when in fact it is about the only thing you know how to say. I would have done better to study &#8220;I don&#8217;t speak Mandarin&#8221; (我不会说普通话).</p>

<p>To learn writing, I&#8217;ve been studying <a href="http://www.amazon.com/Learn-Write-Chinese-Characters-Language/dp/0300057717">Learn to Write Chinese Characters</a> by Johan Björkstén. Reviewers have been very complimentary of its focus on the aesthetics of beautiful and correct drawn characters rather than simply how to print them like a book would. I trust them for now that the focus on beauty is also good for learning.</p>

<p>I&#8217;m still on the lookout for a good dictionary. I use Google translate and wiktionary a lot, but I don&#8217;t like either. I&#8217;d like to find a good online resource that will take a character and give the pinyin and translation, as well as the reverse. A book form would be useful as well of course, though I&#8217;m still working on stroke counting and order, so that makes it hard to look things up.</p>
<img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/WxfZM2E38rw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/chinese-study-480/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/chinese-study-480</feedburner:origLink></item>
		<item>
		<title>NSLog ain’t printf in -Wformat</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/Mj-83JTjx2w/nslog-aint-printf-wformat-477</link>
		<comments>http://robnapier.net/blog/nslog-aint-printf-wformat-477#comments</comments>
		<pubDate>Tue, 13 Apr 2010 15:45:15 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[cocoa]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=477</guid>
		<description><![CDATA[You'd think that printf("%s", 1) and NSLog(@"%s", 1) would throw the same warnings. But you'd be wrong. The compiler can't handle it.]]></description>
			<content:encoded><![CDATA[<p>So say you had this code:</p>

<pre><code>printf("%s", 1);
NSLog(@"%s", 1);
</code></pre>

<p>And you compiled with <code>-Wformat</code>. You might expect both of these lines to kick out a warning:</p>

<pre><code>Format '%s' expects type 'char *', but argument 2 has type 'int'
</code></pre>

<p>You&#8217;d be particularly misled when you went and looked at the definition of <code>NSLog()</code>:</p>

<pre><code>FOUNDATION_EXPORT void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
</code></pre>

<p>Why look there, doesn&#8217;t that look like it should provide format type checking? Oh how foolish. Neither gcc nor clang can actually handle that <code>__NSString__</code> specifier in a robust way. So the first line above will give a useful warning, but the second one will silently compile and later crash. Exciting, I know. You have been warned.</p>

<p><code>-Wformat-nonliteral</code> and <code>-Wformat-security</code> do catch dangerous calls like <code>NSLog(foo)</code>, so <code>__NSString__</code> isn&#8217;t a complete loss, but it&#8217;s a shame we can&#8217;t get type checking here.</p>

<p>There&#8217;s a good discussion of this at <a href="http://stackoverflow.com/questions/1229212/nslog-improper-format-specifier-affects-other-variables]">NSLog(…) improper format specifier affects other variables?</a></p>
<img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/Mj-83JTjx2w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/nslog-aint-printf-wformat-477/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/nslog-aint-printf-wformat-477</feedburner:origLink></item>
		<item>
		<title>iPhone as a career</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/adJvcdT_ofM/iphone-career-474</link>
		<comments>http://robnapier.net/blog/iphone-career-474#comments</comments>
		<pubDate>Sun, 11 Apr 2010 21:22:52 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=474</guid>
		<description><![CDATA[Can iPhone development be full time job? Will it help you get into a "mainstream job" in Java, .NET, etc. Follow your passion, keep producing, the career will follow.]]></description>
			<content:encoded><![CDATA[<p>Prashant P. wrote me recently asking some questions that I thought I&#8217;d answer here. First, can iPhone development be full time job, and second, will it help him get into a &#8220;mainstream job&#8221; in Java, .NET, etc. As he notes, most of the iPhone development he&#8217;s seen has been a part-time rather than full-time job; a side-line rather than a career.<span id="more-474"></span>I&#8217;ll start with the second question first: iPhone is not a gateway to other platforms except Mac. But even that would be foolish. If you want to work on Mac, work on Mac. If you want to work on .NET, work on .NET. Java and C# have a lot in common, but there&#8217;s no reason to learn C# hoping to get a job in Java. If you love Java, then work in Java. If you love C#, work in C#. There are tons of projects to help on for most platforms, and plenty of room to create new ones (open or commercial). Get involved.</p>

<p>I&#8217;m a full-time Mac and iPhone developer today. I got here because I taught myself Mac development because I wanted a Pandora player that didn&#8217;t take over my browser. I read a book, started building my own, discovered PandoraBoy, joined that project and eventually took it over. Then a job opened up for a Mac developer, and because I&#8217;d just been doing what I love to do, I had the background to get that job. When iPhone became a big thing, we Mac developers had a huge head start on Cocoa, so we became iPhone developers. This is how careers can be built by just doing what you love and keeping an eye out for opportunities. I never had to quit my old job to pursue development; I just worked on Mac stuff in the evenings because it interested me. When a career showed up, I was ready.</p>

<p>If you love Java, then work on Eclipse or any of the other Java projects. If you love .NET, there&#8217;s plenty of opportunities to build things there. Don&#8217;t tell employers what you&#8217;d like to be paid for; show them the kind of work you do even when no one is paying you. I&#8217;ve interviewed a lot of people, and this is what I always look for.</p>

<p>To the question of whether iPhone can be a career, I know many people who have made it one and do quite well, and some who have made it one and barely scrape by. But in any case, it&#8217;s more a question of whether you have a passion for it. Follow your passion first and let the career follow. In software development we have the incredible flexibility of pursuing our passion without quitting our day jobs. We can work anywhere, any time, our materials are cheap once you have a computer, and we don&#8217;t have to set up a storefront to sell our goods. Embrace that.</p>

<p>Watch the job postings at <a href="http://cocoadev.jobcoin.com">Jobcoin</a>. They come up quite often. Take on freelance work a piece at a time, or start a small commercial product of your own and see where it takes you. Use <a href="http://linkedin.com">LinkedIn</a>. Recruiters contact me there regularly, so there are definitely jobs out there. Write a blog. But most importantly, keep producing, whether someone is paying you or not. If producing is a chore, you&#8217;re probably chasing the wrong dream.</p>
<img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/adJvcdT_ofM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/iphone-career-474/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/iphone-career-474</feedburner:origLink></item>
		<item>
		<title>Learning Cocoa with other backgrounds</title>
		<link>http://feedproxy.google.com/~r/Cocoaphony/~3/IV6zJxB718M/learning-cocoa-2-467</link>
		<comments>http://robnapier.net/blog/learning-cocoa-2-467#comments</comments>
		<pubDate>Thu, 28 Jan 2010 18:05:18 +0000</pubDate>
		<dc:creator>Rob Napier</dc:creator>
				<category><![CDATA[cocoa]]></category>

		<guid isPermaLink="false">http://robnapier.net/blog/?p=467</guid>
		<description><![CDATA[From a StackOverflow posting. When I teach Cocoa, I always ask the class what their background is in. This generally tells me what they need to unlearn before they&#8217;re ready for Cocoa. Here are some of the things I&#8217;ve found that different groups need to unlearn. For C++ developers: Naming. Correct naming is critical in [...]]]></description>
			<content:encoded><![CDATA[<p><em><a href="http://stackoverflow.com/questions/1043820/what-programming-skills-i-need-to-become-an-iphone-developer/1044525#1044525">From a StackOverflow posting</a>.</em></p>

<p>When I teach Cocoa, I always ask the class what their background is in. This generally tells me what they need to unlearn before they&#8217;re ready for Cocoa. Here are some of the things I&#8217;ve found that different groups need to unlearn.<span id="more-467"></span></p>

<p>For C++ developers:</p>

<ul>
<li><p>Naming. Correct naming is critical in Objective-C. The compiler will not save you. Learn the naming conventions and follow them.</p></li>
<li><p>Dot notation. Dot notation is pleasant to type for experienced Cocoa developers, but extremely confusing to new developers. Dot notation does not mean &#8220;get or set the ivar of the object.&#8221; Dot notation means &#8220;pass the message <code>-foo</code> or <code>-setFoo:</code> to the object.&#8221; These two statements seem very similar, but are in fact radically different. Most importantly, <code>foo</code> and <code>self.foo</code> are not the same thing, though often they may appear to be the same thing. Assigning to the latter will generally retain the object, while the former will not.</p></li>
<li><p>Following up on dot notation, accessors are not mandatory in ObjC, but should be. Always, always use them (except in the accessors themselves of course, and in <code>-dealloc</code>). Do not access your ivars directly. Not even if you see sample code doing it.</p></li>
<li><p>The reason for all of the last three issues is memory management. If you will follow these last three rules, then your memory management will be easy and you will have very few problems. If you do not, and C++ folks often are very bad about this because C++ has such sloppy naming conventions, then you will have terrible memory management problems.</p></li>
<li><p>Objective-C can use C++. I recommend strongly, however, that you keep your C++ and Objective-C separate, and have only a <a href="http://robnapier.net/blog/wrapping-c-objc-20">thin translation layer</a> in Objective-C++. Learn to use NSArray rather than vector, etc.</p></li>
<li><p>C++ developers often get confused about how Singletons are used in ObjC. If you understand the full, correct Singleton pattern, then you need to understand that ObjC generally doesn&#8217;t use it. It&#8217;s ok to have a static in ObjC that holds the &#8220;shared instance&#8221; and that you never free. OS X (phone and Mac) will recover the memory for you at program termination. It&#8217;s ok to have a &#8220;singleton&#8221; that can actually have multiple instances (NSNotificationCenter and many other objects allow this). There is seldom reason to really ensure that you are the one and only instance of the object (if you&#8217;re overloading <code>-release</code>, stop, even if you found the code to do it on Apple&#8217;s site). &#8220;Singletons&#8221; are generally just an instance that happens to be stored in a static and is returned when you asked for the &#8220;sharedController&#8221; or &#8220;sharedFoo&#8221; or whatever.</p></li>
<li><p>Threading is somewhat rare in Cocoa. Most things are done on the Run Loop, which is cooperative multi-tasking. You get asked something, you respond as quick as you can, all on one thread.</p></li>
</ul>

<p>For C developers:</p>

<ul>
<li><p>I push C developers to stay away from Core Foundation (things that start <code>CF</code>). Core Foundation is very useful, but it&#8217;s too easy to let it become a crutch to avoid actually learning Cocoa. It&#8217;s better to first learn Cocoa in ObjC, and then come back and use Core Foundation when you need to.</p></li>
<li><p>Do not be afraid of long descriptive names. Get used to them. Love them.</p></li>
<li><p>Embrace objects. Even the C-based Core Foundation is basically object oriented in C syntax.</p></li>
<li><p>Don&#8217;t forget your C. A lot of Objective-C is done in straight-up C. It&#8217;s just C, really. C++ isn&#8217;t, but Objective-C really, really is just C.</p></li>
<li><p>Objective-C is really C, but Cocoa isn&#8217;t. Cocoa is Smalltalk. And so you really need to study the Model-View-Controller paradigm and live it every day.</p></li>
</ul>

<p>Java/C#:</p>

<ul>
<li><p>Java developers seem to have the hardest time with dot notation. I often just flat-out ban dot notation for former Java developers. Don&#8217;t use <code>foo.bar</code>, just use <code>[foo bar]</code> and <code>[foo setBar:baz]</code>. You will save yourself a lot of headaches. A Java background just seems to make it much harder to break the idea that dot notation is <em>really</em> a method call and nothing else.</p></li>
<li><p>Even more than C++ developers, I have to teach Java developers that they aren&#8217;t going to spawn threads for things. Use the run loop, and do thing asynchronously with callbacks. As a beginner, you may never need to spawn a thread. I write a lot of complex code, and still only spawn maybe a couple of ObjC threads in a major program.</p></li>
<li><p>C# developers (and Windows developers in general) have trouble with Interface Builder. When you create a button in Visual Studio, it writes a bunch of code for you. IB does not write code. IB serializes an object. A NIB is just an object archive. At run time, the NIB is read, and the objects are deserialized.</p></li>
<li><p>Objective-C does not subclass a lot. It uses helper objects (delegation, datasources). If you have a special window that can&#8217;t be closed except in certain circumstances, you don&#8217;t subclass NSWindow (you almost <em>never</em> subclass NSWindow for anything). You assign a delegate to the NSWindow instance, and when it wants to close, it asks its delegate <code>-windowShouldClose:</code>.</p></li>
<li><p>.NET has lots of objects that do similar things in different ways, and each time a new rev comes along, they give you a new set of objects that do those same things in new ways. .NET objects tend to be really smart with lots of little fiddle knobs to configure them. Cocoa objects are dumb, and that&#8217;s why I love them so much. A table view in Cocoa doesn&#8217;t know anything about querying SQL servers. A table view knows how to draw a table. It asks its datasource for what that data should be, and it asks every time it gets ready to draw a cell. It asks its delegate how tall each rows should be and whether a given row may be selected, just at the moment it needs the information. This is backwards of how .NET generally does things.</p></li>
</ul>

<p>And that leads to my biggest point for developers coming from anywhere that isn&#8217;t Smalltalk:</p>

<ul>
<li>It isn&#8217;t about you. It isn&#8217;t about your code. And it isn&#8217;t about your code doing this or that. It&#8217;s first about the user and responding to the user. It&#8217;s second about your code responding to the framework. You don&#8217;t usually tell the framework what to do. It asks you for things when it needs something. You sit and wait for it to talk to you. You&#8217;re not in charge. You don&#8217;t control the runloop; it controls you. You register to be told when things happen, and you indicate that you&#8217;re the object who knows something about something (data for a table for instance). And then you let go, and let Cocoa do the rest. It&#8217;s a very different world. I like it very much.</li>
</ul>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save?linkurl=http%3A%2F%2Frobnapier.net%2Fblog%2Flearning-cocoa-2-467&amp;linkname=Learning%20Cocoa%20with%20other%20backgrounds"><img src="http://robnapier.net/blog/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p><img src="http://feeds.feedburner.com/~r/Cocoaphony/~4/IV6zJxB718M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://robnapier.net/blog/learning-cocoa-2-467/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://robnapier.net/blog/learning-cocoa-2-467</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.475 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-08-06 10:15:08 -->
