Vincent Gable’s Blog

June 7, 2010

Quality is Money

Filed under: iPhone,MacOSX,Programming,Quotes | , , , ,
― Vincent Gable on June 7, 2010

The truth is that an iPad app is neither easier nor harder to make than an iPhone app (or a Mac or Windows app), in any general, reasonable, defensible way. Software doesn’t work like that; we don’t have to work twice as hard to cover twice as many pixels on screen. It’s all about the elusive quality factor.

Matt Legend Gemmell, on iPad App Pricing

Amen!

July 19, 2009

For iPhone and or iPod Touch and or Other Things As Well

Filed under: Announcement,iPhone,MacOSX | , , , , , ,
― Vincent Gable on July 19, 2009

It’s very clear that a program “for Mac OS X” works with any personal computer Apple sells, because they all have “Mac” in their name. Unfortunately, the flavor of OS X that runs on the iPhone and iPod Touch is officially called “iPhone OS” by Apple, which it implies an incompatibility with the iPod Touch, and any future device that doesn’t have “phone” in the name.

I don’t know a good way to unambiguously say that a program is for any iPhone OS device, without tedious enumeration.

“For iPhone OS” sounds like it excludes the iPod Touch.

“For all models of iPhone and iPod Touch” sounds terrible. It will sound even worse when Apple comes out with other iPhone OS devices (“…for iPhone or iPod Touch or iTablet or iFPGA…”).

Apple could help by renaming “iPhone OS” to “Mobile OS X”, but I don’t see this happening.

I personally lean towards using “for iPhone” in general writing, and clarifying, if necessary, in “systems requirements” fine print. This feels closest to how the press covers iPhone OS applications, and of course it’s how Apple named the OS.

I’d love to hear what you call iPhone OS applications, and why.

March 31, 2009

How To Write Cocoa Object Getters

Setters are more straightforward than getters, because you don’t need to worry about memory management.

The best practice is to let the compiler write getters for you, by using Declared Properties.

But when I have to implement a getter manually, I prefer the (to my knowledge) safest pattern,

- (TypeOfX*) x;
{
  return [[x retain] autorelease];
}

Note that by convention in Objective-C, a getter for the variable jabberwocky is simply called jabberwocky, not getJabberwocky.

Why retain Then autorelease

Basically return [[x retain] autorelease]; guarantees that what the getter returns will be valid for as long as any local objects in the code that called the the getter.

Consider,

NSString* oldName = [person name];
[person setName:@"Alice"];
NSLog(@"%@ has changed their name to Alice", oldName);

If -setName: immediately releasees the value that -name returned, oldName will be invalid when it’s used in NSLog. But if the implementation of [x name] used retain/autorelease, then oldName would still be valid, because it would not be destroyed until the autorelease pool around the NSLog was drained.

Also, autorelease pools are per thread; different threads have different autorelease pools that are drained at different times. retain/autorelease makes sure the object is on the calling thread’s pool.

If this cursory explanation isn’t enough, read Seth Willitis’ detailed explanation of retain/autorelease. I’m not going to explain it further here, because he’s done such a through job of it.

Ugly

return [[x retain] autorelease]; is more complicated, and harder to understand then a simple return x;. But sometimes that ugliness is necessary, and the best place to hide it is in a one-line getter method. It’s self documenting. And once you understand Cocoa memory management, it’s entirely clear what the method does. For me, the tiny readability cost is worth the safety guarantee.

Big

return [[x retain] autorelease]; increases peak memory pressure, because it can defer dealloc-ing unused objects until a few autorelease pools are drained. Honestly I’ve never measured memory usage, and found this to be a significant problem. It certainly could be, especially if the thing being returned is a large picture or chunk of data. But in my experience, it’s nothing to worry about for getters that return typical objects, unless there are measurements saying otherwise.

Slow

return [[x retain] autorelease]; is obviously slower then just return x;. But I doubt that optimizing an O(1) getter is going to make a significant difference to your application’s performance — especially compared to other things you could spend that time optimizing. So until I have data telling me otherwise, I don’t worry about adding an the extra method calls.

This is a Good Rule to Break

As I mentioned before, getters don’t need to worry about memory management. It could be argued that the return [[x retain] autorelease]; pattern is a premature optimization of theoretical safety at the expense of concrete performance.

Good programmers try to avoid premature optimization; so perhaps I’m wrong to follow this “safer” pattern. But until I have data showing otherwise, I like to do the safest thing.

How do you write getters, and why?

March 29, 2009

How To Write Cocoa Object Setters

There are several ways to write setters for Objective-C/Cocoa objects that work. But here are the practices I follow; to the best of my knowledge they produce the safest code.

Principle 0: Don’t Write a Setter

When possible, it’s best to write immutable objects. Generally they are safer, and easier to optimize, especially when it comes to concurrency.

By definition immutable objects have no setters, so always ask yourself if you really need a setter, before you write one, and whenever revisiting code.

I’ve removed many of my setters by making the thing they set an argument to the class’s -initWith: constructor. For example,

CustomWidget *widget = [[CustomWidget alloc] init];
[widget setController:self];

becomes,

CustomWidget *widget = [[CustomWidget alloc] initWithController:self];

This is less code, and now, widget is never in a partially-ready state with no controller.

It’s not always practical to do without setters. If an object looks like it needs a settable property, it probably does. But in my experience, questioning the assumption that a property needs to be changeable pays off consistently, if infrequently.

Principle 1: Use @synthesize

This should go without saying, but as long as I’m enumerating best-practices: if you are using Objective-C 2.0 (iPhone or Mac OS X 10.5 & up) you should use @synthesize-ed properties to implement your setters.

The obvious benefits are less code, and setters that are guaranteed to work by the compiler. A less obvious benefit is a clean, abstracted way to expose the state values of an object. Also, using properties can simplify you dealloc method.

But watch out for the a gotcha if you are using copy-assignment for an NSMutable object!

(Note: Some Cocoa programmers strongly dislike the dot-syntax that was introduced with properties and lets you say x.foo = 3; instead of [x setFoo:3];. But, you can use properties without using the dot-syntax. For the record, I think the dot syntax is an improvement. But don’t let a hatred of it it keep you from using properties.)

Principle 2: Prefer copy over retain

I covered this in detail here. In summary, use copy over retain whenever possible: copy is safer, and with most basic Foundation objects, copy is just as fast and efficient as retain.

The Preferred Pattern

When properties are unavailable, this is my “go-to” pattern:

- (void) setX:(TypeOfX*)newX;
{
  [memberVariableThatHoldsX autorelease];
  memberVariableThatHoldsX = [newX copy];
}

Sometimes I use use retain, or very rarely mutableCopy, instead of copy. But if autorelease won’t work, then I use a different pattern. I have a few reasons for writing setters this way.

Reason: Less Code

This pattern is only two lines of code, and has no conditionals. There is very little that can I can screw up when writing it. It always does the same thing, which simplifies debugging.

Reason: autorelease Defers Destruction

Using autorelease instead of release is just a little bit safer, because it does not immediately destroy the old value.

If the old value is immediately released in the setter then this code will sometimes crash,

NSString* oldName = [x name];
[x setName:@"Alice"];
NSLog(@"%@ has changed their name to Alice", oldName);

If -setName: immediately releasees the value that -name returned, oldName will be invalid when it’s used in NSLog.

But if If -setName: autorelease-ed the old value instead, this wouldn’t be a problem; oldName would still be valid until the current autorelease pool was drained.

Reason: Precedent

This is the pattern that google recommends.

When assigning a new object to a variable, one must first release the old object to avoid a memory leak. There are several “correct” ways to handle this. We’ve chosen the “autorelease then retain” approach because it’s less prone to error. Be aware in tight loops it can fill up the autorelease pool, and may be slightly less efficient, but we feel the tradeoffs are acceptable.

- (void)setFoo:(GMFoo *)aFoo {
  [foo_ autorelease];  // Won't dealloc if |foo_| == |aFoo|
  foo_ = [aFoo retain]; 
}

Backup Pattern (No autorelease)

When autorelease won’t work, my Plan-B is:

- (void) setX:(TypeOfX*)newX;
{
  id old = memberVariableThatHoldsX;
  memberVariableThatHoldsX = [newX copy];
  [old release];
}

Reason: Simple

Again, there are no conditionals in this pattern. There’s no if(oldX != newX) test for me to screw up. (Yes, I have done this. It wasn’t a hard bug to discover and fix, but it was a bug nonetheless.) When I’m debugging a problem, I know exactly what setX: did to it’s inputs, without having to know what they are.

On id old

I like naming my temporary old-value id old, because that name & type always works, and it’s short. It’s less to type, and less to think about than TypeOfX* oldX.

But I don’t think it’s necessarily the best choice for doing more to old than sending it release.

To be honest I’m still evaluating that naming practice. But so far I’ve been happy with it.

Principle 3: Only Optimize After You Measure

This is an old maxim of Computer Science, but it bears repeating.

The most common pattern for a setter feels like premature optimization:

- (void) setX:(TypeOfX*)newX;
{
  if(newX != memberVariableThatHoldsX){
    [memberVariableThatHoldsX release];
    memberVariableThatHoldsX = [newX copy];
  }
}

Testing if(newX != memberVariableThatHoldsX) can avoid an expensive copy.

But it also slows every call to setX:. if statements are more code, that takes time to execute. When the processor guesses wrong while loading instructions after the branch, if‘s become quite expensive.

To know what way is faster, you have to measure real-world conditions. Even if a copy is very slow, the conditional approach isn’t necessarily faster, unless there is code that sets a property to it’s current value. Which is kind of silly really. How often do you write code like,

[a setX:x1];
[a setX:x1]; //just to be sure!

or

[a setX:[a x]];

Does that look like code you want to optimize? (Trick question! You don’t know until you test.)

Hypocrisy!

I constantly break Principle 3 by declaring properties in iPhone code as nonatomic, since it’s the pattern Apple uses in their libraries. I assume Apple has good reason for it; and since I will need to write synchronization-code to safely use their libraries, I figure it’s not much more work to reuse the same code to protect access to my objects.

I can’t shake the feeling I’m wrong to do this. But it seems more wrong to not follow Apple’s example; they wrote the iPhone OS in the first place.

If you know a better best practice, say so!

There isn’t a way to write a setter that works optimally all the time, but there is a setter-pattern that works optimally more often then other patterns. With your help I can find it.

UPDATE 03-30-2009:

Wil Shiply disagrees. Essentially his argument is that setters are called a lot, so if they aren’t aggressive about freeing memory, you can have thousands of dead objects rotting in an autorelease pool. Plus, setters often do things like registering with the undo manager, and that’s expensive, so it’s a good idea to have conditional code that only does that when necessary.

My rebuttal is that you should optimize big programs by draining autorelease pools early anyway; and that mitigates the dead-object problem.

With complex setters I can see why it makes sense to check if you need to do something before doing it. I still prefer safer, unconditional, code as a simple first implementation. That’s why it’s my go-to pattern. But if most setters you write end up being more complex, it might be the wrong pattern.

Really you should read what Wil says, and decide for yourself. He’s got much more experience with Objective-C development then I do.

March 25, 2009

Crazy Idea: Using iPhones During Interviews

Filed under: Uncategorized | , , ,
― Vincent Gable on March 25, 2009

Using an iPhone as a resource during a job interview is an idea worth considering. An iPhone can google answers to trivial questions Unlike a laptop, it can be used while people face each other, and it’s small enough not to obscure someone. Additionally, it can’t compile and test code, so candidates must still think everything through in their head.

Adding technology to an interview, just because it’s technology, is a bad idea for exactly the same reasons that just putting computers in a classroom isn’t helpful without special curriculum.

But since an iPhone is so unobtrusive, I think it’s uses are worth considering.

In technical interviews, it’s very common for the interviewee to have a question about an API or other detail. The standard practice is for them to agree with the interviewer on an assumed answer and run with it. This works. But it might be interesting to have the real answer available.

Another open question is if google-fu is something that should be tested during an interview. If so, an iPhone might be one way to do it.

Do you have an idea for incorporating some technology into a face-to-face interview?

February 18, 2009

Competing Software Engineering Approaches

Filed under: Cocoa,Programming,Quotes,UNIX | , , , , ,
― Vincent Gable on February 18, 2009

Tim Bray,

…Palm’s approach is
radically different from both Android’s and Apple’s. Since they’re all here
at more or less the same time, running the
same Web browser on roughly
equivalent hardware, this represents an unprecedented experiment in
competitive software-engineering approaches.

Language Framework Notes
Apple Objective-C Cocoa Old-school object-oriented language compiled to the metal; general-purpose UI
framework with roots reaching back to NeXT.
Android Java Android Java language, custom VM, built-from-scratch UI
framework aimed at small-form-factor devices, fairly abstraction-free, based
on “Actions” and “Intents”.
web OS JavaScript “Mojo” All Web technology all the time. Innovative and visually-impressive
“card”-based UI.

(I think it’s interesting to see Windows Mobile on the list:

Windows Mobile C/C++ Windows CE/.NET Micro Philosophically tries to bring Windows to the phone. When I did WinCE development it felt like doing C++ for a Windows OS from the past.

)

I see way too many other factors to attribute success/failure of the devices to the language. So I wouldn’t call this an experiment.

But it is interesting how much development for each platform diverges at a fundamental level!

Historically most operating systems —
UNIX, OS/2, Linux, Windows, Solaris, Mac (Classic and OS X) — were predominantly, written in C/C++. While each platform has it’s own frameworks, they all have strong support for C++ development. (Although Mac OS X has is slowly dropping support for it’s C/C++ “Carbon” API, and Windows wants to be moving to C# .NET)

It’s really cool to see mobile platforms doing something radically different from each other. There are good arguments for each approach — may the best one win.

February 9, 2009

No Ducking Way!

Filed under: Design,Quotes,Uncategorized | , , , , ,
― Vincent Gable on February 9, 2009

I’ve finally found an example of, someone intentionally typing “ducking” on their iPhone,

Plotting routes to meetings based on who I’m currently ducking. It’s good for exercise. Also that time iPhone was correct- I meant ducking.

Obviously we can’t have a spellchecker suggesting profanity. But is it really so wrong to just leave it alone? Can we trust that if someone says something that strongly they really meant it?

Word 2008 seems to try, bless it’s heart. It won’t suggest or correct, “Mike Lee” (at least when it’s written as two words).

But it still can’t stand one of the heavy seven (original MP3). Word gives it the scarlet underline. That strikes me as odd. I wish I knew the story behind it. Is it actually a dangerously common typo? Is it statistically more taboo? Did someone just make a Puritan judgement call, and decide people wanted to be corrected for writing it? (UPDATE 2009-11-18: apparently it is the worst swear word in the World, at least according to that cute story.)

Ask yourself, are obscenity filters a Bad Idea, or an Incredibly Intercoursing Bad Idea?

December 8, 2008

Optimize CPU Usage of Your Website

Filed under: Programming,Quotes,Usability | , , , , ,
― Vincent Gable on December 8, 2008

The thing is, web developers should test their pages for CPU usage the same as app developers do. And anytime a page is idle, CPU usage should be at 0%. Same as with any other app.

Brent Simmons

Last quarter notebooks outsold desktops for the first time. Netbooks, and iPhones have been exploding in popularity as well. That means a significant number of your website’s visitors will be running off a battery, and since battery life decreases proportionally with CPU load, you really do owe it to your users to do this. The internet shouldn’t be something you have to be plugged into a power outlet to use.

October 9, 2008

Function Over Brand

Filed under: Design,Quotes | , ,
― Vincent Gable on October 9, 2008

There is something to be said for the fact that the phone with the strongest brand in the world has no visible branding whatsoever on its front face.

John Gruber on the iPhone. But you knew what phone he was talking about.

I’ve always been deeply opposed to any branding strategy that values a brand over a product. Adding branding to something’s “face” makes it harder to use, because it adds visual noise to the very part of the thing you have to interact with (and figure out how to use). For example, an “Intel Inside” sticker next to a keyboard is one more square-thing you have to rule out when looking for the right button to press.

Powered by WordPress