Wednesday, October 5th, 2011
I would not be here today, doing what I do, if not for Steve Jobs. Considering I never met the man, he had an incredible impact on my career, my outlook on life, and my definition of success.
Goodbye, Steve. Rest easy.
See also, Remembering Steve Jobs on Nullary Sources.
Wednesday, September 7th, 2011
I’ve been busy — really busy.
Much of that energy obviously has been going in to running Springs & Struts, my Mac and iOS consulting business. I’ve been using the Springs & Struts name for over two and a half years now and 2011 has been our best year yet. I’ve shipped several apps for happy clients already this year. I’ve also begun to experiment with using subcontractors (and being a subcontractor myself), an effort which has been quite successful. In fact, I no longer think of Springs & Struts as just another name for myself — instead, it has become its own thing. I couldn’t be happier.
I’ve also been on a few podcasts. I recently made an appearance on my friend Kanen Flowers’s new podcast, Scruffy Thinking. I was on the episode “I Do All My Writing in Latex” with Kanen, Ron Brinkmann and Merlin Mann (holy shit) talking about Markdown and text documents and text editors and things like that. I think I did a pretty good job of pretending to sound intelligent. Additionally, some clips that were cut from that episode (and other Scruffy Thinking episodes) ended up on “The Real @cbarrett” — including the Dirk Gently–esque story of how Kanen and I met.
You can also hear me on the teasers for the upcoming Postmodem podcast, with my friends Phillip Bowden and Patrick Thomson. It’s a little more free form than Scruffy Thinking, but we discuss things of general interest to nerds — movies, comics, music, tech, and so on. So far we’ve only released a couple of lower quality clips to whet the appetite, but we have a few full episodes in the can waiting on editing. Eventually they’ll see release, and we’re already planning to record more.
Also worth noting is that Nullary Sources, the link blog I co-host with ‘Ili Butterfield, is still going strong. We’ve been posting a lot of great content that’s tough to sum up in one go — instead I recommend just going and checking it out.
And of course I’m on the usual cadre of social networks. I recommend my venerable Twitter account as well as my activity on Quora — a relatively new Q&A service that I’ve really been enjoying lately. I’ve written over 300 answers about a wide variety of subjects.
All of this is my very roundabout way of saying that while I haven’t necessarily been writing as much here as I’d like to, I’ve been putting content out there if you know where to find it.
Wednesday, September 7th, 2011
As if there wasn’t already reason enough, Florian Mueller on FOSS Patents drops a bombshell. Maybe the bombshell.
It’s all there — all your worst fears about Android, confirmed by filings for Oracle v. Google. The twofacedness about “open”. Giving preferential treatment to specific OEMs (specifically Motorola).
And this, which I already understood implicitly but it’s still sickening to see it spelled out like this, from a 2009 document entitled “Android Strategy and Partnerships Overview”:
“Android isn’t a new product to monetize; it’s a new medium to drive monetization on existing products.”
Combined, it’s all enough to make me physically ill. I’m staying out of this mess. There’s no way something this gross can be sustainable. And if it somehow does succeed — if Google’s story plays out the same way as Microsoft’s did (which is what all of this really reminds me of) — count me out anyway.
Also posted on Quora.
Monday, August 8th, 2011
Mike Haertel, original author of GNU grep:
#1 trick: GNU grep is fast because it AVOIDS LOOKING AT
EVERY INPUT BYTE.
#2 trick: GNU grep is fast because it EXECUTES VERY FEW
INSTRUCTIONS FOR EACH BYTE that it *does* look at.
Fantastic knowledge dump. I wasn’t aware of the Boyer-Moore algorithm that GNU grep uses, but it’s definitely being filed away for future use.
Reminds me of this post by Peter Ammon, about optimizing searching in Hex Fiend, which is also worth reading.
(Via Anant Narayanan.)
Monday, July 18th, 2011
Say you’ve got an NSFetchedResultsController with a predicate like project.enabled == YES. (Imagine this app shows a list of to-do items, organized into projects.) Now say you enable (or disable) a project. What will NSFetchedResultsController do?
I assumed that it would fire insert or delete events for items coming in or out of the set of items that matched the predicate. What actually happens is that NSFetchedResultsController does not pick up these changes.
Perhaps a simpler way of stating it is that NSFetchedResultsController does not seem to track changes when the predicate contains a key path that drills down into a relationship.
Workaround
You can force NSFetchedResultsController to pick up the changes, but it’s a bit ugly. Here’s an example:
[project setValue:[NSNumber numberWithBool:YES] forKey:@"enabled"];
for (NSManagedObject *todo in [project valueForKey:@"todos"]) {
[todo willChangeValueForKey:@"project"];
[todo didChangeValueForKey:@"project"];
}
Posting these “empty” KVO notifications appears to fix the problem.
Radar and sample project
I’ve filed this as radar 9790804. Muchos gracias to ‘Ili Butterfield for whipping up a sample project demonstrating this bug.
Friday, July 15th, 2011
Matt Haughey, the creator of MetaFilter, recently sat down with the Willamette Week for an interview. Most of the interview is about MetaFilter and is quite good, but this part caught my eye:
Geeks who know how to program and make things should be able to make a small thing that runs forever and make $100,000 a year and live off that. I mean, what is wrong with that? It’s an awesome goal.
I never got that message anywhere in the tech community. Like, what is wrong with making a decent living in doing something you love forever? And then people put that down as a “lifestyle business.” Or ask, “How are you going to change the world or make the next Facebook?”
It’s like nobody sings unless they want to be Britney Spears. That’s stupid—we should all sing in bars three nights a week if we like it and get paid as professional musicians. Who says you have to be a superstar? I hate the whole “rock-star programmer” thing where you have to make the next Facebook.
I couldn’t agree more. Quitting my job was easily the best decision I ever made, despite the hardships.
As Matt touches on, in large parts of the tech community, independent life is not even really considered as a path to success — it’s seen as dilettantey and unserious. This has always sat really wrong with me: my heroes were people like Brent Simmons and Gus Mueller and Wil Shipley. These guys were out there and selling Mac software simply because it made them happy.
I guess that attitude is somewhat anachronistic; the wider tech industry has celebrated the easy money, get rich quick, dot com lifestyle for some time now.
I’m going to continue to do what makes me happy, though. Why would I do anything else?
Tuesday, July 5th, 2011
My current set up in Xcode 3 runs something like this:
- For day to day development, I use the Debug configuration. Pretty standard. No real correlation between running the product on the device and simulator.
- When I want to do — or simply try out — a Release style build, I switch to the release configuration. I do this from time to time just as a sanity check. 99% of the time I use Release, it’s on the device.
- Even more rarely — once a week at the maximum — I need to do a release. In my case, these releases are usually milestone builds for clients, just to show how the application is progressing.
Even still, I have a couple of requirements about these release builds:
Firstly, I need to be able to run and test the exact build I’m going to send to a client. Seems foolish to do anything else.
Also, I have a somewhat complicated, but I don’t think unreasonable release process. It goes something like this: After running and doing a final smoke test on the release build, I run a script I’ve developed. This script:
- Copies the dSYM from build/Release to dSYMs/
- Commits
- Adds a tag for the current version (based on the CFBundleVersion)
- Bumps the CFBundleVersion
- Commits
- Runs the PackageApplication script included with Xcode to create a .ipa file from the .app in build/Release
- Opens a Mail message with that .ipa file attached
It also has support for parsing & incrementing the CFBundleShortVersionString key and a couple other things.
So to be clear, I’m backing up the dSYMs for each release in source control and trusting my email provider to host the builds of old versions of the applications (only reason I’ve found to need those EXACT old versions is to re-sign them).
Also note that this script isn’t run from Xcode, and in fact it wouldn’t be a good idea to do that. (I’m working on a version that has interactive capabilities to prompt the user if it notices odd things, like if the build it finds is older than a certain threshold or signed in a way that’s probably wrong.)
I think these are all pretty reasonable requirements. It’s certainly not the most Xcode-y way of going about doing this, but it makes sense to me and I think is at least somewhat internally consistent.
Where Xcode 4 falls down
Firstly, the new default location for built products — which is in ~/Library/Developer/Xcode/DerivedData/$AppName-$RandomSeriesOfDigits1 and seems to have been chosen so schemes and workspaces don’t step on each other (totally reasonable) — totally breaks my script. I’m totally not against having to add more options to my script (plus some sensible defaults) for specifying which scheme or workspace or whatever is wanted, and then having my script look up the location for that scheme. But there doesn’t seem to be any way to do that.
(Moving my built products back into SRCROOT seems like it’s begging for disaster further down the road, and I’m really hesistant to do this.)
I also find the combination of schemes & actions totally unnecessary. I don’t understand what problem they’re trying to solve. I’ve never found configurations, especially with .xcconfig files, to be inadequate.
The default actions are both too limiting — in my workflow there are multiple types of “Archiving” (more on that word later) — and also way too broad — testing and analyzing and running are all totally overlapping for me. I also can’t imagine a workflow where I’d want to configure more than one of the actions for a particular scheme — that seems like something you’d want in a target. Maybe I’m missing something.
Aside: Core Data
One problem not mentioned above is Xcode 4’s handling of Core Data. All of the below applies to the only released version, 4.0.2.
- You cannot change the model version identifier. rdar://problem/9592700 which is duped to rdar://problem/9006105 (which I see as open).
- When you create a new model version, what you enter for the model’s name in the into the wizard doesn’t stick. I.e. “MyApp (5) 2” is the default and no matter how many times I tried to change it to “MyApp (6)”, the resulting file would be created as “MyApp (5) 2”. Infuriating.
Returning to the main thrust of the post, about Xcode 4’s failings
Because of the above problems with Core Data, I still need to use Xcode 3 somewhat frequently — at the very least to deal with Core Data model files. It’s really unclear to me what exactly is going to propagate back from Xcode 4 in terms of schemes, actions, etc. Not creating an addition scheme seems to not break things for me, but I have not played with this out of fear of breaking it.
Finally, I’d like to address “archiving”. The standard archive action frankly blows for one big reason: I have multiple machines. It’s largely worthless to have half the dSYMs on one machine, half on the other. Moving the dSYMs into source control and keeping the .ipas in email is a pretty good solution and works well. Having to dick around in the Organizer is so annoying. (The Organizer itself seems to be a random collection of functionality the designers that weren’t iTunesy enough to fit in the main UI.)
This situation honestly sucks, and I see no way to use Xcode 4 for releasing software (especially when it involves Core Data) — for the foreseeable future I’ll continue to use Xcode 3 for doing so.
(One last thing: Xcode 4 is a total boor on a 13” screen. It’s nearly impossible for me to use comfortably. (If you tell me my font’s too big I will hurt you.))
Tuesday, April 12th, 2011
For a quite a while now, my friend ‘Ili Butterfield and I have been talking about starting a linkblog. Much to the surprise of both of us, however, it actually happened.
We call it Nullary Sources. (Be glad we didn’t use the original name, which was an awful takeoff on “Daring Fireball”).
While Nullary Sources has no set theme, as ‘Ili mentioned when he introduced it last week, so far we’ve put together pleasing mix of current events, video game music and baseball — pretty different from this site I would say.
The site is still young and we’re still exploring the format, but we haven’t really done anything like what I’ve been posting here, so I’m hoping to have plenty of juice to continue writing about technology and small business in this space. (Programming note: I’ve been intentionally keeping it quiet here the past week to give Nullary Sources a chance to stand up on its own. I’m pleased with how it’s gone so far.)
But who knows. Like most things on the internet, it’s pretty ephemeral — we’ve signed no contracts and have made no outside commitments. But at the same time I’m pretty fired up about it. I don’t think there’s anything else quite like it out there, and people seem to really like it so far.
Anyway, I hope you folks enjoy it. Here are a couple posts to give you a flavor for what we’ve published so far.
Sunday, April 10th, 2011
“If Mercurial is so awesome, why doesn’t someone make HgHub?”
If your company’s mission statement is “like X but for Y” you’re in trouble. There’s nothing in there that will inform the thousands of decisions you’ll make about your product in the future. You’ll be simply copying X over and over again — forever a clone.1
Truth be told, Git is probably the least interesting part of GitHub. In fact, GitHub will probably still be around when the next generation version control systems appear, and GitHub’s mission — embodied in statements like “GitHub is the best way to collaborate with others” and “GitHub: Social Coding” — will lead them smoothly into the future.
My advice to someone interested in creating another Mercurial-based tool for code hosting2 would be to examine GitHub’s features and see what you think you could do better. What gaps are there in GitHub’s offerings? What class of users are served poorly by GitHub?3 How can you reduce the costs of switching to your service? Are those people going to be willing to pay you money? If you can answer these questions — and decide to use Mercurial for the basis for your system — you’ll be well on your way to developing a serious GitHub competitor.
Friday, April 1st, 2011
Short answer: A convenience constructor is one that performs object allocation & initialization in one step & returns an autoreleased object to the caller.
Long answer: In Cocoa, object allocation and initialization are separate steps. Take this code for example:
NSString *string = [[[NSString alloc] init] autorelease];
NSString *string2 = [NSString string];
The second line uses a convenience constructor, but they are equivalent. Here’s a breakdown:
[NSString alloc]
allocates the correct amount of memory (depending on the number of instance variables and other runtime-need storage) on the heap for an object of the NSString class and returns a pointer to it. (Think of this as a malloc and a bzero, conceptually.)
[... init]
initializes the above object. This is where your code runs to set up the object and get it into whatever initial state it needs to be in.1
[... autorelease]
autoreleases the object. This is critical in Cocoa — memory management patterns dictate that callers should return autoreleased objects if they no longer need to hold a reference to them. A Cocoa programer will expect a method like +string to return an autoreleased object (how autorelease works is a bit out of scope).2
Why would you want this? It’s significantly simpler. to write, especially if you’re passing the object to another method and never actually holding a reference to it yourself.
I originally wrote this on Quora, and have lightly edited it to fit this space.
nothing, hence.
Previously, Dickbar