<?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/"
	>

<channel>
	<title>Lap Cat Software Blog</title>
	<atom:link href="http://lapcatsoftware.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://lapcatsoftware.com/blog</link>
	<description>Coding under the close supervision of cats</description>
	<pubDate>Tue, 16 Jun 2009 17:27:19 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>WWDC: Busted</title>
		<link>http://lapcatsoftware.com/blog/2009/06/16/wwdc-busted/</link>
		<comments>http://lapcatsoftware.com/blog/2009/06/16/wwdc-busted/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 17:27:19 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Apple]]></category>

		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=187</guid>
		<description><![CDATA[WWDC is over, and I&#8217;m now home safe, somewhat sound. I truly enjoyed my time at DEN, as well as the brief visit to San Francisco in between. I met some people, failed to meet a lot of people, saw some old friends and old enemies (I&#8217;ll let you decide who&#8217;s who), fell in love, [...]]]></description>
			<content:encoded><![CDATA[<p>WWDC is over, and I&#8217;m now home safe, somewhat sound. I truly enjoyed my time at DEN, as well as the brief visit to San Francisco in between. I met some people, failed to meet a lot of people, saw some old friends and old enemies (I&#8217;ll let you decide who&#8217;s who), fell in love, got married, got divorced, killed a man, and won the NBA championship. Ok, maybe not all that, but I did pay too much for brunch.</p>
<p>For me, the most useful part of WWDC was the labs. At no other time of the year do you get unfiltered, one-on-one contact with Apple engineers. Surprisingly, I even managed to avoid punching any of them. I spent hours in the lab talking with the QuickTime, WebKit, and CFNetwork teams about various issues I&#8217;ve encountered. One engineer even volunteered to exercise his Gdb Fu on my MBP.</p>
<p>There&#8217;s much more to WWDC than just the technical side, though. In addition to the valuable information I learned, I was also able to bring home a backpack, three shirts, a Red Sweater button, and the common cold.</p>
<p>I do have one complaint about WWDC (not the food). We stood in line for over an hour &mdash; outside in the chilly wind &mdash; to get into the keynote, but it wasn&#8217;t until 15 minutes after the keynote started that we finally got in &hellip; to the overflow room. I understand that there&#8217;s not enough space for everyone in the main room, but Apple knew well in advance both what time the keynote starts and how many people were attending WWDC, so there is absolutely no excuse for failing to open the doors in time for everyone to get in the building and sit down. Really, it&#8217;s shameful. I would like to hear an apology from Apple for this major logistical screwup. It gave me a bad impression at the very beginning of my first WWDC and first keynote. Not to mention that tickets are quite expensive, yet non-attendees following on the internet had better access to the keynote than me. WWDC organizers, you suck!</p>
<p>I&#8217;m not allowed to say anything else about the conference, because of the NDA. I may be breaking it just by telling you I was there. Nonetheless, I&#8217;m going to share one little Snow Leopard secret with you. To distinguish it from Leopard, the latest WWDC seed has a new default Desktop background image: Hello Kitty.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/06/16/wwdc-busted/feed/</wfw:commentRss>
		</item>
		<item>
		<title>WWDC or bust</title>
		<link>http://lapcatsoftware.com/blog/2009/06/05/wwdc-or-bust/</link>
		<comments>http://lapcatsoftware.com/blog/2009/06/05/wwdc-or-bust/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 15:39:25 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Apple]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Rogue Amoeba]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=185</guid>
		<description><![CDATA[Thanks to the generosity of Rogue Amoeba, the Ford Foundation, and listeners like you, I&#8217;ll be attending WWDC this year. If you want to find me there, I&#8217;ll be the one wearing a Rogue Amoeba T-shirt.
Actually, I&#8217;ll be one of the ones wearing a Rogue Amoeba T-shirt. The cute one.
No, sorry, that&#8217;s Paul. Let&#8217;s face [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to the generosity of <a href="http://www.rogueamoeba.com/" title="Rogue Amoeba | Quality Audio Software for Mac OS X">Rogue Amoeba</a>, the Ford Foundation, and listeners like you, I&#8217;ll be attending <a href="http://developer.apple.com/wwdc/" title="Apple Developer Connection - Worldwide Developers Conference 2009">WWDC</a> this year. If you want to find me there, I&#8217;ll be the one wearing a Rogue Amoeba T-shirt.</p>
<p>Actually, I&#8217;ll be one of the ones wearing a Rogue Amoeba T-shirt. The cute one.</p>
<p>No, sorry, that&#8217;s Paul. Let&#8217;s face it: in our fab four, I&#8217;m the Ringo. (Or for you younger folks, the Michael Anthony.) My plan is to earn millions hanging out with those other guys and making thumping noises in the background.</p>
<p>This will be my first time attending WWDC. I&#8217;m really looking forward to meeting fellow developers such as <a href="http://brockerhoff.net/" title="Rainer Brockerhoff">Rainer Brockerhoff</a> and &hellip; umm &hellip; err &hellip; yeah. Anyway, hope to see you there!</p>
<p>To those poor, unfortunate souls who won&#8217;t be at the Moscone Center on Monday, I offer a consolation: the official 2009 WWDC keynote home game! The rules are straightforward. (1) Whenever Phil Schiller says something, drink. Heavily.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/06/05/wwdc-or-bust/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Radar Bug Friday: Bonus Edition</title>
		<link>http://lapcatsoftware.com/blog/2009/03/13/radar-bug-friday-bonus-edition/</link>
		<comments>http://lapcatsoftware.com/blog/2009/03/13/radar-bug-friday-bonus-edition/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 14:15:08 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Apple]]></category>

		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=126</guid>
		<description><![CDATA[Though Apple Bug Friday has gone the way of Rip and Robert Van Winkle, I&#8217;m bringing it back for one last, glorious, remunerative show. Opening act: some weird dancing fool who people last admired in the 80s. Take your choice.
The continuing failure of Apple to provide a searchable bug database has forced developers to take [...]]]></description>
			<content:encoded><![CDATA[<p>Though Apple Bug Friday has gone the way of Rip and Robert Van Winkle, I&#8217;m bringing it back for one last, glorious, remunerative show. Opening act: some weird dancing fool who people last admired in the 80s. Take your choice.</p>
<p>The continuing failure of Apple to provide a searchable bug database has forced developers to take matters into their own hands. Witness <a href="http://openradar.appspot.com/" title="Open Radar">Open Radar</a>. I&#8217;ve never been one to join any club that would have me as a member &mdash; nor have I been one to be invited to any clubs &mdash; so I&#8217;ve decided to host <a href="http://lapcatsoftware.com/rdar/index.html" title="Radar Problems">my own list of bugs.</a> Keep in mind that these are not all of the Radar bugs I&#8217;ve ever filed. They&#8217;re not even all of my currently unfixed bugs. They are, however, a very large subset of my currently unfixed bugs. (I&#8217;d say the cardinality is somewhere between aleph-null and aleph-one.)</p>
<p>For legal, moral, and comical reasons, I&#8217;ve edited the bugs to remove confidential information. I&#8217;ve also left out the embarrassing nude photos I attach for ADC. (I would stop uploading them, but engineering always requests more.) I hope that you find these bugs useful and also enjoy reading them as much as I enjoyed writing them. In fact, it&#8217;s a metaphysical certainty that you will enjoy reading them at least that much.</p>
<p>After imparting this vital information, I leave you to go in, through, and beyond &hellip; for coffee and a donut.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/03/13/radar-bug-friday-bonus-edition/feed/</wfw:commentRss>
		</item>
		<item>
		<title>dSYM in your bundle or just happy to see me</title>
		<link>http://lapcatsoftware.com/blog/2009/01/20/dsym-in-your-bundle-or-just-happy-to-see-me/</link>
		<comments>http://lapcatsoftware.com/blog/2009/01/20/dsym-in-your-bundle-or-just-happy-to-see-me/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 15:55:14 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Apple]]></category>

		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Unix]]></category>

		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=111</guid>
		<description><![CDATA[It&#8217;s been a while since I posted last. Rest assured that I did survive the Y2K9 disaster, though not unscathed. Since bloggers and other entertainers &#8212; such as Brian Williams &#8212; are required by law to offer a retrospective at the end of a year, I&#8217;ve been scanning the Top 10 lists of Top 10 [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I posted last. Rest assured that I did survive the Y2K9 disaster, though not unscathed. Since bloggers and other entertainers &mdash; such as Brian Williams &mdash; are required by law to offer a retrospective at the end of a year, I&#8217;ve been scanning the Top 10 lists of Top 10 lists of things that we have gained and lost in 2008. Next to our collective sanity, the most significant loss of the year was <a href="http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/" title="Stabs is deprecated">STABS</a>. Actually, it wasn&#8217;t so much lost as deprecated. This means that we can&#8217;t expect any new features (or bugs!), and support for STABS debugging symbols may disappear in some future operating system, say, Windows -400. (I assume that the countdown of version numbers from 95 to 7 is intended to accurately represent the software&#8217;s regression.) In the transition from STABS to DWARF, it was thought (by the people who matter, viz., me) that we also lost the ability to ship debugging symbols with our apps. Luckily, it was discovered (again, by the people who matter) that we did not lose this ability.</p>
<p>Developers sometimes need to give users a debug version of an application. For example, a user may be experiencing an exception or crash that the developer cannot reproduce. Including debugging symbols with the app allows the reports to be fully symbolized. With STABS, the symbols reside within the app&#8217;s executable, so shipping them is trivial. The DWARF with dSYM format, on the other hand, puts the debugging symbols in a separate file. (To be accurate, a separate file within a separate bundle, but we&#8217;ll ignore that fact for this sentence.) By default, Xcode creates <code>MyApp.app.dSYM</code> in the same folder as <code>MyApp.app</code>, and indeed, Leopard&#8217;s crash reporter can locate <code>MyApp.app.dSYM</code> in the same folder as <code>MyApp.app</code> regardless of which folder they&#8217;re in on disk. Theoretically, then, you could have the user put a <code>.dSYM</code> in the same folder as the app. However, making the user do this would be, in a word, lame. In two words, pretty lame. Moreover, it doesn&#8217;t work at all on Tiger. Pretty, pretty lame.</p>
<p>When I face an insoluble problem, my tendency is to step back and get philosophical. Why do I exist? Why does the universe hate me? Who was the real Darrin? More to the point: what is an app? Essentially, an app is a command-line tool in a box with a pretty bow. (Another iSweater, just what I needed!) An app&#8217;s main executable file is located in the directory <code>Contents/MacOS</code> of the <code>.app</code> bundle. You can even launch an app from the command line, e.g.,</p>
<pre><code>/Applications/Safari.app/Contents/MacOS/Safari</code></pre>
<p>assuming that you haven&#8217;t deleted Safari for security reasons. So how does this information help us? It doesn&#8217;t &mdash; I&#8217;m just killing time here. However, it&#8217;s worth noting that if you build the Release configuration of a command-line tool project, Xcode by default creates <code>MyTool.dSYM</code> in the same folder as <code>MyTool</code>. In both Leopard and Tiger, the crash reporter can locate the <code>.dSYM</code> there. Thus, you would expect that the crash reporter can also locate <code>MyApp.app/Contents/MacOS/MyApp.dSYM</code> when your app crashes. And you would be right! (Of course, you would expect this because I just told you, whereas originally you would have expected to try a bunch of stuff and fail, like putting <code>MyApp.app.dSYM</code> in <code>MyApp.app/Contents/MacOS</code>.)</p>
<p>The beauty of this technique is that it works not only for the app&#8217;s main executable but also for other embedded executables such dynamic libraries and frameworks. When a crash occurs involving <code>MyFramework.framework</code>, the crash reporter will find</p>
<pre><code>MyApp.app/Contents/Frameworks/MyFramework.framework/Versions/A/MyFramework.dSYM</code></pre>
<p>You can build the framework in a separate Xcode project and copy the product along with its embedded <code>dSYM</code> into your app&#8217;s bundle, and the symbols will be found at crashtime. (That&#8217;s runtime with a bang.) In Tiger, the line numbers of the source code files can sometimes be a little off in the crash reports; this may be due to bugs in the handling of stripped binaries by <code>atos</code>, which I mentioned in my <a href="http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/" title="Stabs is deprecated">earlier post</a>.</p>
<p>Now that we know where to put the debugging symbols in the app bundle, how do we get them there? Manual copying is unthinkable (like giving David Pogue a copy of OS X GM before ADC members, or putting Leon Panetta in charge of the CIA). If your entire build process is not automated, you should give up software development immediately and look for another career; I recommend professional ice dancing. You could write a shell script to copy <code>MyApp.app.dSYM</code> from the <code>build</code> directory, but that&#8217;s only slightly less annoying than having your users copy it to <code>/Applications</code>, because it&#8217;s something that Xcode should do itself.</p>
<p>Fortunately, the  <a href="http://developer.apple.com/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/100-Build_Setting_Reference/build_setting_ref.html" title="Xcode Build Setting Reference">Xcode build setting reference</a> tells us how to configure this. Or so one <a href="http://developer.apple.com/search.php?q=DWARF_DSYM_FOLDER_PATH" title="No Results Found">would think</a>. Well, at least the relevant build settings are found in the environment variables &hellip; after you&#8217;ve written your shell script. The Xcode build transcript normally doesn&#8217;t show environment variables, but you can add a run script build phase to your target and check the option &#8220;Show environment variables in build log&#8221;. The environment variables reveal the default values for <code>DWARF_DSYM_FOLDER_PATH</code> and <code>DWARF_DSYM_FILE_NAME</code>, which Xcode uses in creating the <code>dSYM</code> file. Although you won&#8217;t find them in the target&#8217;s list of build settings, you can create them yourself in the User-Defined section. To embed the <code>dSYM</code> within the app bundle, just set <code>DWARF_DSYM_FOLDER_PATH</code> to <code>$(CONFIGURATION_BUILD_DIR)/$(EXECUTABLE_FOLDER_PATH)</code> and <code>DWARF_DSYM_FILE_NAME</code> to <code>$(EXECUTABLE_NAME).dSYM</code>. These settings should work for both apps and frameworks.</p>
<p>My beard has grown longer over the course of this post, and my knees are starting to ache, so it&#8217;s time to wrap it up, tip my hat to the new year, and meet the new boss.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2009/01/20/dsym-in-your-bundle-or-just-happy-to-see-me/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Review of PGP boot disk encryption</title>
		<link>http://lapcatsoftware.com/blog/2008/11/23/review-of-pgp-boot-disk-encryption/</link>
		<comments>http://lapcatsoftware.com/blog/2008/11/23/review-of-pgp-boot-disk-encryption/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 17:43:57 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Apple]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Unix]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=109</guid>
		<description><![CDATA[This is my first official software review. I normally don&#8217;t review software other than my own &#8212; Radioshift, five thumbs up, buy now! &#8212; because there&#8217;s no profit in it (like US auto makers). However, Dave Dribin asked me to do it, and apparently Dave gets whatever he asks for.
PGP Whole Disk Encryption introduced pre-boot [...]]]></description>
			<content:encoded><![CDATA[<p>This is my first official software review. I normally don&#8217;t review software other than my own &mdash; <a href="http://www.rogueamoeba.com/radioshift/" title="Radioshift: Radio on your schedule">Radioshift</a>, five thumbs up, <a href="http://www.rogueamoeba.com/radioshift/buy.php" title="Purchase Radioshift">buy now</a>! &mdash; because there&#8217;s no profit in it (like US auto makers). However, <a href="http://twitter.com/ddribin/statuses/954248758" title="@ddribin">Dave Dribin</a> asked me to do it, and <a href="http://openradar.appspot.com/faq" title="Open Radar FAQ">apparently</a> Dave gets whatever he asks for.</p>
<p><a href="http://www.pgp.com/products/wholediskencryption/" title="PGP Whole Disk Encryption">PGP Whole Disk Encryption</a> introduced pre-boot authentication for Intel Macs in <a href="http://www.pgp.com/insight/newsroom/press_releases/wde_for_mac_osx.html" title="PGP Corporation Delivers Pre-Boot Authentication to PGP Whole Disk Encryption for Mac OS X Users">version 9.9</a>. Pre-boot authentication allows you to encrypt your Mac&#8217;s entire internal hard drive. I wrote a form of whole disk encryption myself in <a href="http://www.knoxformac.com/" title="Knox&mdash;Simple secure encryption and backup for Macintosh computers">Knox</a>, but that was for non-boot disks. Prior to installing PGP 9.9, I had been using Apple&#8217;s built-in FileVault to encrypt the home directory of <a href="http://support.apple.com/kb/SP24" title="MacBook Pro (Late 2006) - Technical Specifications">my MacBook Pro</a>. I became interested in whole disk encryption for the laptop after I discovered that neither third-party developers nor <a href="http://lapcatsoftware.com/blog/2008/05/10/security-alert-mac-os-x-1052-subverts-filevault/" title="SECURITY ALERT: Mac OS X 10.5.2 subverts FileVault">Apple itself</a> could be trusted not to write personal data outside your home directory.</p>
<p>This review is not intended to be comprehensive, because again, I&#8217;m not being paid for it &hellip; though if a certain corp whose name is a certain acronym would send a certain something my way, I would certainly be appreciative, wink, wink, nudge, nudge, say no more. Before you charge the software to Mr. Underhill&#8217;s American Express card (want the number?), I highly recommend that you study the <a href="https://supportimg.pgp.com/guides/pgpDesktopMac_99_usersguide_en.pdf" title="PGP Desktop v9.9 for Macintosh User Guide">user guide</a> for important caveats. My aim is simply to describe my experience and to pass along some undocumented tips I picked up along the way.</p>
<p>I purchased Whole Disk Encryption for Mac, affectionately known as WDE4M, from <a href="http://na.store.pgp.com/whole_disk_encryption_mac.html" title="PGP Store NA - PGP Whole Disk Encryption for Mac">PGP&#8217;s online store</a> for 119 US Dollars (more than a bread box, less than a nano), and I received my license key by email within 10 minutes, so no problems there. It took slightly longer to encrypt my boot disk. The entire process required around 8 hours for the MBP&#8217;s 200 GB internal HD. (Actually, according to Mac OS X, it&#8217;s 186.3 GB. These are sometimes given the label GiB, which stands for Grrrr, ithoughtihadmore Bytes.) Obviously, you&#8217;ll want to let it to run overnight, unless you need a break from watching your grass grow.</p>
<p>In reviewing WDE4M, the first concern is security. When you boot your Mac from the internal drive, you get the PGP login screen. At this point, the Mac OS X volume has not yet been mounted. Until you enter your password at the PGP login screen, the entire boot volume remains encrypted. As long as you choose a good password (mine is <code>Joshua</code>), all of your data is safe. Note that it is still possible to boot your Mac from a different disk such as a DVD or an external hard drive. It&#8217;s even possible to boot into Firewire target disk mode (assuming you have a Firewire port: ha, ha!). However, you won&#8217;t be able to mount the Mac OS X volume on the internal drive, because without PGP running, you have nothing more than a partition full of encrypted bytes. Indeed, PGP modifies the partition table of your disk to add its special boot partition, so I would recommend starting with a single volume of data. I previously had multiple partitions and volumes on the MBP, but I found that to be a PITA regardless of PGP.</p>
<p>After you authenticate successfully at the PGP screen, the computer boots normally into Mac OS X. It is crucial to realize that when you&#8217;re booted into Mac OS X, your data is vulnerable. PGP will decrypt on the fly any bytes that the OS asks for. Thus, if someone steals your laptop while it&#8217;s running OS X, you&#8217;re screwed. You can try logging out or setting a screensaver password, but those types of protection can often be defeated. The only way to guarantee safety is to shut down or reboot. Thankfully, WDE4M protects against so-called &#8216;cold boot&#8217; attacks (unlike FileVault).</p>
<p>The next issue for WDE4M beyond security is performance. On my MBP with a 2.33 GHz Intel Core 2 Duo and 2 GB RAM, I&#8217;ve found performance to be a non-issue. Admittedly, I&#8217;ve never done speed tests, but I don&#8217;t perceive my system to be sluggish or slower from PGP WDE. It seems as Zippy<sup>TM</sup> as ever. I&#8217;ve heard from some sources (e.g., the shoe shine guy) that PGP&#8217;s encryption / decryption is much faster than FileVault&#8217;s. The only operations that seem a little slow are copying extremely large, multi-GB files from another disk; the entire contents of these files must be encrypted as they&#8217;re copied onto the internal drive.</p>
<p>The final issue I&#8217;ll discuss is backups. If you care about your data, you must back it up, otherwise you will lose it at some point. If your data is important enough to protect with WDE4M, it&#8217;s important enough to back up. (Note that I made two full backups of my internal drive before attempting to encrypt it. I also downloaded my brain into an android.) No backup strategy is perfect for everyone, so we must each follow one that fits our needs. For example, the majority of computer users follow the strategy that experts term &#8216;Divine Intervention&#8217;. I had to experiment quite a bit before I found something that worked for me: in the end I turned to good ol&#8217; <code>dd</code>.</p>
<p>My procedure for backing up my PGP-encrypted internal hard drive is simple. Even a caveman could do it. (Yes, Unix has been around that long.) First I mount an external backup drive that has enough free space to fit my entire internal drive. Then I boot into the Mac OS X installer: this can be done from a partition on the external drive, from a DVD, or from a USB stick. A Mac OS X installer volume is not required to perform the backup &mdash; you could use another Mac, for example &mdash; but I use an installer so that I can boot from the MBP and take advantage of its Firewire 800 port. Finally I launch Terminal and enter the following:</p>
<pre><code>dd if=/dev/disk0 of=/Volumes/backups/disk0.dmg</code></pre>
<p>Running <code>dd</code> takes 5 to 7 hours back up the MBP&#8217;s 186 GiB HD to a FireWire 800 external HD. I might be able to expedite the process by tweaking the <code>bs</code> operand of <code>dd</code>, but I&#8217;m running the backup overnight anyway, so I favor simplicity and reliability over speed. Afterward, I have a byte-for-byte backup of my entire internal drive. Any machine running PGP can mount the <code>dmg</code> with the correct password, so the backup is suitable for file-based restoration. A machine without PGP installed, in contrast, will fail to mount the <code>dmg</code>, finding no mountable file systems, because the entire file system is encrypted.</p>
<p>From a security standpoint, a byte-for-byte backup is not ideal, because it has the same encryption key as the original. Once you start modifying files on your internal drive again, it&#8217;s conceivable that a <code>diff</code> between the backup and original could reveal something interesting. However, few people in the world have any hope of success in extracting readable information through such an investigation, certainly not the casual thief, and of course backing up your files unencrypted would be infinitely worse! I&#8217;m not trying to keep any state secrets (my WMD is curled up sleeping on his cat bed), but if you&#8217;re the paranoid type &mdash; and my hidden video cameras show me that you are &mdash; you should be able to encrypt your backup drive with a different key before you create the <code>dmg</code> with <code>dd</code>. Indeed, you could create one big encrypted <code>dmg</code> with Disk Utility and put the backup <code>dmg</code> inside it. I haven&#8217;t tried this myself, so I&#8217;d be interested to hear whether it&#8217;s viable. Anyway, this Russian doll approach would provide ample protection if your data were stolen by the Russian mafia, or if you were a member of it.</p>
<p>In the event of catastrophic data loss, e.g., my laptop is swallowed by a whale, I can use the backup to easily transform some other disk into a bootable clone of the laptop:</p>
<pre><code>dd if=/Volumes/backups/disk0.dmg of=/dev/disk1</code></pre>
<p>If you have an external drive the same size or slightly larger than your internal drive, you can skip the <code>dmg</code> and create a bootable clone directly:</p>
<pre><code>dd if=/dev/disk0 of=/dev/disk1</code></pre>
<p>The disadvantage of this procedure is that any extra space on the backup drive would be unusable. I have a few 500 GB (465 GiB, sigh) external HD&#8217;s, so it makes more sense for me to save multiple backups on each drive.</p>
<p>You can boot a clone of your PGP-encrypted drive from another machine regardless of whether the machine has PGP installed on its internal drive. However, it may take a couple of spontaneous reboots before you can login to Mac OS X, much like a software update, so you need to be patient. (Perhaps it&#8217;s updating the boot cache?) Also, booting the clone from the original machine is to be avoided. As a test of my backup procedure, I cloned my MBP to an external drive and then booted the MBP from the clone. The MBP did successfully boot from the external drive, and I was able to login to Mac OS X, but I was surprised to find that the Mac OS X volume was mounted from the internal rather than the external drive. This bizarre behavior puzzled me until I read <a href="http://developer.apple.com/technotes/tn2006/tn2166.html" title="Technical Note TN2166">Secrets of the GPT</a>, which I already mentioned in my <a href="http://lapcatsoftware.com/blog/2008/11/02/what-about-sony/" title="What about Sony?">last post</a>. The technical note warns, &#8220;Be careful when doing a block-for-block copy of a GPT disk. The GUID in the partition table header that identifies the disk (and the GUIDs in each partition entry) are meant to be <b>globally unique</b>, and Apple&#8217;s system software relies on this feature.&#8221; If you do what I did, &#8220;the computer might boot from either the original or the copy in an unpredictable fashion (perhaps toggling from boot to boot).&#8221; Oops! That reminds me of the time I got <code>mount</code> to show two volumes with the same BSD name &hellip; but that&#8217;s a tale for another day.</p>
<p>WDE4M comes with PGP Desktop, which has a number of useful features such as handling public-private key-pairs and allowing encryption of AOL Instant Message sessions between PGP users. PGP Desktop can automatically encrypt email as well, but one thing to look out for is that it attempts this by default. I kept getting &#8220;Invalid Authentication Certificate&#8221; warnings in <code>Mail.app</code>, and I initially blamed this on Leopard, because the warning window did not indicate that it was from PGP, and I had just installed Leopard prior to installing PGP. You can turn off the email encryption feature in the Messaging Security preferences of <code>PGP.app</code>. Hopefully PGP will put its name on the warning window in the next software update to PGP 9.9, so that it&#8217;s clear to the user where the warning is coming from.</p>
<p>Overall, in summary and conclusion, to wrap it all up, finally: I find WDE4M to be a well-engineered product, it does what it&#8217;s supposed to do, viz., protect all of your data, I have no regrets about buying it, and I have no reservations about encouraging other people to buy it too.</p>
<p><b>P.S.</b> If you like WDE4M from PGP, you might also enjoy <a href="http://www.rogueamoeba.com/airfoil/" title="Airfoil for Mac and Windows">Airfoil</a> from <a href="http://www.rogueamoeba.com/" title="Rogue Amoeba | Quality Audio Software for Mac OS X">Rogue Amoeba</a>. Nudge, nudge, say no more.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/11/23/review-of-pgp-boot-disk-encryption/feed/</wfw:commentRss>
		</item>
		<item>
		<title>What about Sony?</title>
		<link>http://lapcatsoftware.com/blog/2008/11/02/what-about-sony/</link>
		<comments>http://lapcatsoftware.com/blog/2008/11/02/what-about-sony/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 16:45:16 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Apple]]></category>

		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=107</guid>
		<description><![CDATA[Yesterday I purchased an 8 GB Sony Micro Vault USB drive.

I&#8217;m sure it&#8217;s a fine device, though it&#8217;s far too early at this point to comment on its functionality. What I found immediately noteworthy was the packaging.
The drive came encased in a hard plastic tomb roughly ten times its size.

Why such a large package for [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I purchased an <a href="http://www.sony.net/Products/Media/Microvault/products/usm-l/" title="Sony Micro Vault">8 GB Sony Micro Vault</a> USB drive.</p>
<p><img src="http://lapcatsoftware.com/downloads/img/sony-drive.png" alt="USB drive"/></p>
<p>I&#8217;m sure it&#8217;s a fine device, though it&#8217;s far too early at this point to comment on its functionality. What I found immediately noteworthy was the packaging.</p>
<p>The drive came encased in a hard plastic tomb roughly ten times its size.</p>
<p><img src="http://lapcatsoftware.com/downloads/img/sony-front.png" alt="Front of package"/></p>
<p>Why such a large package for such a small item? The answer lies on the back.</p>
<p><img src="http://lapcatsoftware.com/downloads/img/sony-back.png" alt="Front of package"/></p>
<p>Not an inch to spare! Clearly, the size of the package was justified by the need for operating instructions on the back. Or important warnings before use. Or something? Actually, it&#8217;s not clear at all, because the font is ridiculously tiny.</p>
<p>If we take a close-up, we can see that the text does indeed provide us with instructions and warnings&hellip;</p>
<p><img src="http://lapcatsoftware.com/downloads/img/sony-instructions.png" alt="Front of package"/></p>
<p>&hellip;for opening the package. In seven languages, no less. And what do those instructions tell us?</p>
<p><b>Use scissors</b>.</p>
<hr />
<p><em>Postscript:</em> You would think that finding the right storage size for your needs would be easy. The Finder told me that the files I wanted to put on the USB drive were 7.1 GB. Thus, an 8 GB drive should be plenty big. Right? Right?</p>
<p>For some reason that escapes me and that has somehow, astonishingly, escaped class action lawsuits, the drive manufacturers and the operating system manufacturers count GB differently. The capacity of my Micro Vault is 8,019,509,248 bytes, which according to Sony is 8 GB but according to Apple is 7.5 GB. Well, ok, so I lost half a gig right out the box, but I still have more than I need. Right? Right?</p>
<p>The USB drive came with a Master Boot Record partition scheme for Windows machines. This was no good for my purpose, because I was going to boot Intel Macs from the drive. Thus, I repartitioned in Disk Utility with a GUID Partition Table scheme, which is used by Intel Macs. When I was done, I was shocked to discover that the drive now contained less free space than I need for my files! What happened?</p>
<p>The answer can be found at <a href="http://developer.apple.com/technotes/tn2006/tn2166.html" title="Technical Note TN2166">Secrets of the GPT</a>. Apple considers my USB drive to be a &#8220;big disk&#8221;. (Have they seen the photo above?) As a consequence, they ignored my choice of one partition in Disk Utility and added a second, 200 MB partition on the drive for EFI device drivers, <q>although Apple does not currently use it for anything.</q> Moreover, they added 128 MB of empty space after my main partition <q>to make it easier for future system software to manipulate the partition map in ways that we can&#8217;t anticipate currently.</q> That&#8217;s great for my great-grandchildren, but at present, I want that space.</p>
<p>My workaround for the problem was to reformat the drive using an Apple Partition Map scheme. This takes up less space on my &#8220;big disk&#8221;. Although APM is used by PowerPC Macs, it turns out that Intel Macs can boot from an APM drive too.</p>
<p>If APM didn&#8217;t work, I was going to use scissors.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/11/02/what-about-sony/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Working without a nib, Part 7: The empire strikes back</title>
		<link>http://lapcatsoftware.com/blog/2008/10/20/working-without-a-nib-part-7-the-empire-strikes-back/</link>
		<comments>http://lapcatsoftware.com/blog/2008/10/20/working-without-a-nib-part-7-the-empire-strikes-back/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 16:36:13 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Apple]]></category>

		<category><![CDATA[Cocoa]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=105</guid>
		<description><![CDATA[I recently received an email from Steve Jobs. He told me that he has read all of my blog posts. I found this ridiculous, so I replied, &#8220;You&#8217;re full of it!&#8221; Shockingly, he wrote back. &#8220;Actually,&#8221; he said, &#8220;all of the new apps of the past few years are nibless.&#8221; He then described the Apple-sanctioned [...]]]></description>
			<content:encoded><![CDATA[<p>I recently received an email from Steve Jobs. He told me that he has read all of my blog posts. I found this ridiculous, so I replied, &#8220;You&#8217;re full of it!&#8221; Shockingly, he wrote back. &#8220;Actually,&#8221; he said, &#8220;all of the new apps of the past few years are nibless.&#8221; He then described the Apple-sanctioned technique of writing a nibless application.</p>
<p>In <a href="http://lapcatsoftware.com/blog/2007/06/04/working-without-a-nib-part-2-also-also-wik/" title="Working without a nib, Part 2: Also Also Wik">previous</a> <a href="http://lapcatsoftware.com/blog/2007/11/25/working-without-a-nib-part-6-working-without-a-xib/" title="Working without a nib, Part 6: Working without a xib">posts</a> of this series, I was forced to use obscure workarounds such as <code>+[NSObject poseAsClass:]</code> and <code>method_exchangeImplementations()</code> to prevent <code>NSApplicationMain()</code> from trying to load a nib. Jordy Rose of <a href="http://belkadan.com/" title="Belkadan Software">Belkadan Software</a> suggested to me that the easiest way to prevent <code>NSApplicationMain()</code> from trying to load a nib would be to avoid calling <code>NSApplicationMain()</code> at all. Instead, you would just call <code>-[NSApplication run]</code>. However, I was worried that <code>NSApplicationMain()</code> might do something else important (like phone home to get permission to launch). We don&#8217;t know, because we don&#8217;t have the source code.</p>
<p>I&#8217;m still waiting for the source code, but Steve did indicate that it was safe to skip <code>NSApplicationMain()</code>. Thus, there&#8217;s no need for tricksy runtime manipulation, except perhaps to prove your mad programming skills. Mad, that is, in the sense of having worn one ring for too long. Steve also affirmed that <a href="http://lapcatsoftware.com/blog/2007/06/17/working-without-a-nib-part-4-setapplemenu/" title="Working without a nib, Part 4: setAppleMenu">our call</a> to <code>-[NSApplication setAppleMenu:]</code>, a method that Apple removed from the API, will continue to work until there&#8217;s a replacement API. Indeed, Apple is working on some kind of replacement. Excellent! <code>/me plays air guitar.</code> So if you&#8217;re counting at home, it&#8217;s now (1) Exchange support and (2) Nibless support.</p>
<p>He didn&#8217;t mention the <b>Open Recent</b> menu, so it appears that <a href="http://lapcatsoftware.com/blog/2007/07/10/working-without-a-nib-part-5-open-recent-menu/" title="Working without a nib, Part 5: Open Recent menu">my ugly hack</a> is still required for non-document-based apps. This cannot be considered part of the Apple-sanctioned technique, though it is sanctioned by me, which is more desirable, because my approval comes in seven delicious flavors. I&#8217;ve updated Nibless for Leopard in light of Steve&#8217;s revelations and am making version 2.0 available for <a href="http://lapcatsoftware.com/downloads/NiblessLeopard2.zip" title="NiblessLeopard2.zip">immediate download</a>. This is major progress, because it already puts me two versions ahead of <a href="http://www.videolan.org/vlc/" title="VLC media player">VLC.</a></p>
<p>So long, Steve, and thanks for all the fish!</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/10/20/working-without-a-nib-part-7-the-empire-strikes-back/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cocoa memory management for smarties, Part 3: accessors</title>
		<link>http://lapcatsoftware.com/blog/2008/10/05/cocoa-memory-management-for-smarties-part-3-accessors/</link>
		<comments>http://lapcatsoftware.com/blog/2008/10/05/cocoa-memory-management-for-smarties-part-3-accessors/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 21:50:52 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Cocoa]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=96</guid>
		<description><![CDATA[This post is not over until Minnesota Fats says it is, or until I figure out why he played in Iowa. In the meantime, let&#8217;s talk about getters and setters. A setter is distinguished by the prefix set, while a getter is distinguished by not having the prefix get. Got it? Getters and setters come [...]]]></description>
			<content:encoded><![CDATA[<p>This post is not over until Minnesota Fats says it is, or until I figure out why he played in Iowa. In the meantime, let&#8217;s talk about getters and setters. A setter is distinguished by the prefix <code>set</code>, while a getter is distinguished by not having the prefix <code>get</code>. Got it? Getters and setters come in pairs; collectively, they are commonly known as <em>accessor methods</em>, less commonly as <em>American Airlines</em> or <em>pocket rockets</em>.</p>
<p>Accessor methods provide encapsulated access to an object&#8217;s <em>instance variables</em> &mdash; <em>instancvariabls</em> for short. If your <em>instancvariabl</em> is an Objective-C object (in Freudian terms, an <code>id</code>),  your accessors should almost always look like this:</p>
<pre>
-(id) thing
{
	return [[_thing retain] autorelease];
}

-(void) setThing:(id)aThing
{
	if (_thing != aThing)
	{
		[_thing release];
		_thing = [aThing retain];
	}
}
</pre>
<p>You can <code>copy</code> rather than <code>retain</code> in <code>setThing:</code> if the class of <code>aThing</code> conforms to <code>&lt;NSCopying&gt;</code>.</p>
<p>It may seem redundant to <code>[[_thing retain] autorelease]</code> in <code>thing</code>, but this has an important purpose. (A special purpose, if you will, which you&#8217;ll want to use every chance you get.) Simply returning <code>_thing</code> in <code>thing</code> does not suffice, as the following code demonstrates.</p>
<pre>
1 id something = [myObject thing];
2 [myObject setThing:nil]; // Clear out the thing.
3 [something doSomething];
</pre>
<p>In line 3, your app will go boom. I&#8217;ve seen it argued (on bathroom stalls, for example) that the caller ought to <code>[[myObject thing] retain]</code> on line 1 because of this possibility, but that&#8217;s simply not the caller&#8217;s responsibility. It&#8217;s an implementation detail of <code>myObject</code> that <code>thing</code> returns an <em>instancvariabl</em> which <code>setThing:</code> releases. Moreover, the caller could inadvertently call <code>setThing:</code> by calling some other method that calls <code>setThing:</code> rather than by calling <code>setThing:</code> directly. With <code>[[_thing retain] autorelease]</code>, <code>thing</code> ensures that <code>_thing</code> will not be deallocated in the caller&#8217;s scope (as long as the caller doesn&#8217;t do anything stupid, like call out Minnesota Fats).</p>
<p>No discussion of accessors is complete without talking about thread safety. In order to write thread-safe accessors, you should first drink a bottle of whiskey. This is required because writing thread-safe accessors is a fool&#8217;s errand. Don&#8217;t do it. Don&#8217;t try it. Don&#8217;t even think about. Redesign your code to avoid the need for thread-safe accessors. If you feel you must, however, then you should acquaint yourself with <a href="http://developer.apple.com/technotes/tn2004/tn2123.html" title="CrashReporter">Technical Note TN2123</a>, because you&#8217;ll find yourself referring to it frequently. It&#8217;ll be like a nightmare, just getting (and setting) worse and worse. But at least the salad dressing will be good.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/10/05/cocoa-memory-management-for-smarties-part-3-accessors/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Postlude in C4[2] major</title>
		<link>http://lapcatsoftware.com/blog/2008/09/08/postlude-in-c42-major/</link>
		<comments>http://lapcatsoftware.com/blog/2008/09/08/postlude-in-c42-major/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 16:51:42 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Rogue Amoeba]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=94</guid>
		<description><![CDATA[I&#8217;m back safe, cat in lap, from C4[2]. This year&#8217;s theme was &#8220;Don&#8217;t ship until it&#8217;s ready, i.e., early and often, and don&#8217;t price too low, i.e., make it free.&#8221; I would like to thank @rentzsch for hosting the best conference I&#8217;ve ever attended (with the possible exception of the Marty Feldman fan club). I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m back safe, cat in lap, from <a href="http://rentzsch.com/c4/2dates" title="C4[2]">C4[2]</a>. This year&#8217;s theme was &#8220;Don&#8217;t ship until it&#8217;s ready, i.e., early and often, and don&#8217;t price too low, i.e., make it free.&#8221; I would like to thank @rentzsch for hosting the best conference I&#8217;ve ever attended (with the possible exception of the Marty Feldman fan club). I&#8217;d also like to suggest that C4[3] be moved to neighboring Wisconsin, which is home to @rentzsch as well as to &#8220;Fun&#8221;, as @dylanbr (or was it @bruzenak?) correctly noted.</p>
<p>The highlight of the weekend was meeting a lot of people &mdash; basically, everyone, including my coworkers &mdash; for the first time. Unfortunately, however, they came to realize that I&#8217;m a complete fraud who has been contracting out all of my coding to @macgeek02. As a result, I was fired by @PBones, fired by qdc (@???), and retroactively fired by @markonen. Fortunately, I had a backup plan: I stowed away in @wilshipley&#8217;s luggage and am now living in his basement.</p>
<p>C4[2] was not brought to you by the letter &#8216;w&#8217;. For some strange reason, the Apple Store refuses to sell individual keycaps. Disaster was avoided, though, when @PBones genius-ly performed an emergency transplant. |hat a relief that \as!</p>
<div><img src="http://lapcatsoftware.com/downloads/img/backslash-key.jpg" alt="backslash key"/> <img src="http://lapcatsoftware.com/downloads/img/w-key.jpg" alt="w key"/></div>
<p>Another disaster was avoided when I failed to get into a fight. There were many opportunities. The much anticipated battle for supremacy over Radioshift between myself and @kickingbear never materialized. A little anticipated battle over tunes was quickly resolved when @mikeash chose Dire Straits. Apparently, drunkenbatman was too afraid to show after hearing about my unresolved anger over crashing our WebKit apps. On the other hand, the unresolved anger of @jimcorreia over stealing his chair was redirected toward @chockenberry.</p>
<p>I was pleasantly surprised to learn that someone other than my cat and my parole officer reads my blog. I won&#8217;t name names, for the same reason that &#8220;Hustler&#8221; comes in a plain, brown wrapper. I won&#8217;t name everyone I met at C4 either, because there are [2] many, but please know that I enjoyed talking with you and that I&#8217;ve put all of your names in an SQLite database, of course.</p>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/09/08/postlude-in-c42-major/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cocoa memory management for smarties, Part 2: working with a nib</title>
		<link>http://lapcatsoftware.com/blog/2008/08/25/cocoa-memory-management-for-smarties-part-2-working-with-a-nib/</link>
		<comments>http://lapcatsoftware.com/blog/2008/08/25/cocoa-memory-management-for-smarties-part-2-working-with-a-nib/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 16:51:28 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
		
		<category><![CDATA[Cocoa]]></category>

		<category><![CDATA[Vienna]]></category>

		<guid isPermaLink="false">http://lapcatsoftware.com/blog/?p=83</guid>
		<description><![CDATA[Well, it&#8217;s back to work for the moment. I was offered the VP slot, but I had to turn it down because they refused to accept the NDA: my name would be on the ticket, but nobody could talk about me publicly. Also, they wouldn&#8217;t get rid of the brown M&#38;Ms. I am waiting for [...]]]></description>
			<content:encoded><![CDATA[<p>Well, it&#8217;s back to work for the moment. I was offered the VP slot, but I had to turn it down because they refused to accept the NDA: my name would be on the ticket, but nobody could talk about me publicly. Also, they wouldn&#8217;t get rid of the brown M&amp;Ms. I am waiting for an offer by email from another guy, but I don&#8217;t hold out much hope, since I&#8217;m also waiting for him to learn how to use email.</p>
<p>In <a href="http://lapcatsoftware.com/blog/2008/07/28/cocoa-memory-management-for-smarties-part-1-release-me-not/" title="Cocoa memory management for smarties, Part 1: release me not">part 1 of this series</a> I talked about Cocoa memory management. For a summary of that post, load it in your browser, select all, and pass it to the Summarize system service. And now for something completely the same, in part 2 I&#8217;m going to talk about Cocoa memory management. As you all know, I love nibs. I find them to be a very human-friendly interface, much like the gom jabbar. A nib file contains archived Objective-C objects that are instantiated when the nib is instantiated, so their memory needs to be managed just as objects instantiated programmatically. Fortunately, if the nib File&#8217;s Owner is an <code>NSWindowController</code> or (new in Leopard) <code>NSViewController</code>, the File&#8217;s Owner takes care of the memory management automatically. Otherwise, it&#8217;s your job.</p>
<p>According to the <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/chapter_3_section_3.html#//apple_ref/doc/uid/10000051i-CH4-SW6" title="Nib Objet Retention">documentation</a>, <q>Objects in a nib file are initially created with a retain count of 1. As it rebuilds the object hierarchy, however, Cocoa autoreleases any objects that have a parent or owning object, such as views nested inside view hierarchies. By the time the nib-loading code is complete, only the top-level objects in the nib file have a positive retain count and no owning object. This makes the top-level objects a potential memory leak if your code does not assume responsibility for them.</q> If you look at your nib with the icon view in Interface Builder, the top-level objects consist of everything except the proxy objects such as File&#8217;s Owner, First Responder, and (new in Leopard) Application. Thus, top-level objects include not only windows but also contextual menus, array controllers, etc. For example, <a href="http://vienna-rss.sourceforge.net/vienna2.php" title="Vienna">Vienna&#8217;s</a> <code>MainMenu.nib</code>, pictured below, contains 14 top-level objects. (Kids, don&#8217;t try this at home.)</p>
<div><img src="http://lapcatsoftware.com/downloads/img/vienna-mainmenu-nib.png" alt="MainMenu.nib"/></div>
<p>By the way, the <code>MainMenu.nib</code> file, or whatever is specified by <code>NSMainNibFile</code> in <code>Info.plist</code>, is actually a special case, because the File&#8217;s Owner is <code>NSApplication</code> (or whatever is specified by <code>NSPrincipalClass</code>). You don&#8217;t need to worry about its memory management either, although the objects in the nib will usually remain in memory for the lifetime of the app. On termination, <code>NSApplication</code> may or may not choose to <code>release</code> those objects, as it pleases, so don&#8217;t depend on any code in <code>dealloc</code>. Cleaning up memory on app termination is like sweeping your floor right before a tornado hits.</p>
<p>In order to manage the memory of the nib&#8217;s top-level objects, you&#8217;ll need a reference to them. The method <code>-[NSNib instantiateNibWithOwner: topLevelObjects:]</code> is handy in this respect. The <a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSNib_Class/Reference/Reference.html#//apple_ref/occ/instm/NSNib/instantiateNibWithOwner:topLevelObjects:" title="NSNib Class Reference">documentation</a> of the <code>(NSArray **) topLevelObjects</code> argument may be a little confusing, though: <q>On input, a variable capable of holding an <code>NSArray</code> object. On output, this variable contains an autoreleased <code>NSArray</code> object containing the top-level objects from the nib file.</q> Although the <code>NSArray</code> is autoreleased, the top-level objects themselves are not. Each object in the <code>NSArray</code> will have a retain count of at least 2. Thus, after the <code>NSArray</code> is deallocated and releases its objects, they will each still have a retain count of at least 1. A typical way to handle this is as follows.</p>
<pre><code>
@interface MyObject : NSObject
{ NSArray * _topLevelObjects; }
@end

@implementation MyObject

-(id) init
{
	self = [super init];
	if (self)
	{
		NSNib * nib = [[[NSNib alloc] initWithNibNamed:@"MyNib" bundle:nil] autorelease];
		if (nib &amp;&amp; [nib instantiateNibWithOwner:self topLevelObjects:&amp;_topLevelObjects])
		{
			// The array is autoreleased, so we need to retain it.
			// Release the objects now so that they'll be deallocated along with the array.
			[[_topLevelObjects retain] makeObjectsPerformSelector:@selector(release)];
		}
	}
	return self;
}

-(void) dealloc
{
	[_topLevelObjects release];
	[super dealloc];
}

@end
</code></pre>
<p>If you use a different method to instantiate the nib, such as <code>+[NSBundle loadNibNamed:owner:]</code>, or if you don&#8217;t want to keep an array of the top-level objects, you&#8217;ll need to create an <code>IBOutlet</code> for each top-level object in the nib and release the objects in <code>dealloc</code> along with any other ivars.</p>
<p>A major caveat for do-it-yourself nib loading is that even if you take care to release your top-level objects, you can still get a memory leak if you use Cocoa bindings in your nib. This occurs when an object in the nib binds to the File&#8217;s Owner. The File&#8217;s Owner never gets deallocated in this case, and thus neither do the top-level objects. Again, <code>NSWindowController</code> and <code>NSViewController</code> already take care of this problem automatically, but you&#8217;ll need to deal with it if the File&#8217;s Owner is not one of those classes or their subclasses. Basically, there are three possible solutions:</p>
<ol>
<li>Unbind the bindings programmatically. You&#8217;ll need to do this elsewhere than the File Owner&#8217;s <code>dealloc</code>, which won&#8217;t get called unless you unbind.</li>
<li>Bind to a different object in the nib rather than to the File&#8217;s Owner.</li>
<li>Don&#8217;t use Cocoa bindings and nibs, because they&#8217;re teh suck.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://lapcatsoftware.com/blog/2008/08/25/cocoa-memory-management-for-smarties-part-2-working-with-a-nib/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
