Vincent Gable’s Blog

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?

“They’re Not Getting It”

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

Writing is communication. I’ve always considered the clearest writing the best writing, because it communicates better. That’s why I believe you shouldn’t have to “get” good writing; good writing explains itself.

There has been some criticism of the classic The Elements of Style, because it didn’t follow it’s own advice. Critics call it a mistake, but many people think it’s an intentional joke. Assuming it’s a joke, I think it’s still a black-mark, because educated people aren’t getting it. Jokes that get in the way of what you are trying to say aren’t funny enough to justify themselves. In general, if people don’t get what you are saying, it’s your fault for not explaining it well.

Here’s an offending passage, as you can see it breaks it’s own advice.

The subject of a sentence and the principal verb should not, as a rule, be separated by a phrase or clause that can be transferred to the beginning.

How droll.

Now, The Elements of Style is a classic that’s been informing writers for generations. That success can’t be argued against. If confusing meta-humor is the reason for it, then I can’t contest that.

But it’s not clear to me that the specifically confusing and self contradictory humor has been key. For example, John Gruber says he loves the book because it takes it’s own advice,

I think what makes it special is that it’s so self-exemplifying; it recommends vigorous straightforward prose using vigorous straightforward prose.

If people aren’t getting your jokes, the onus is on you — in exactly the same way it’s your responsibility to make sure your jokes are funny.

Lemur CATTA and the Author’s Burden

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

Mike Lee had an interesting idea for improving comments on blogs. Before someone can post a comment, they have to pass a reading comprehension test, to show they read the article they are commenting on. He called his implementation Lemur CATTA

It’s a good idea, especially for certain communities. But the implementation rubbed me wrong from day one. My problem was that the questions were automatically generated.

I feel like it’s the author’s burden to make their work as accessible to readers as they can. If they are placing a barrier in front of commenters, they should do everything they can to make sure the barrier is effective at blocking the bad, but easily permeable to the good. I don’t feel Auto-generated questions are compatible with that responsibility.

There’s a callousness to auto-generated questions. The author is essentially saying, “Yeah, I took many hours to write this post, and I’m going to inconvenience every reader who wants to reply, but damned if I take a few minutes to write these questions myself”. And that just rubs me the wrong way.

To be fair, writing reading comprehension questions is harder then it seems — at least when I’ve tried it. Maybe a computer is more effective at generating quizzes then a prose writer. (But I doubt it’s more effective then a prose writer with practice.) And auto-generation has all kinds of benefits. It can be applied to comments, and real-time discussions, for example. But sometimes the human touch is more comforting. It gives an assurance that the author cares about what you have to say, and worked through any problems you might be having with the comment system.

More info on Lemur CATTA at lemurcatta.org.

March 17, 2009

Mutable @property and Copy Gotcha

Filed under: Bug Bite,Cocoa,Objective-C,Programming | , , ,
― Vincent Gable on March 17, 2009

If you have a @property for an object who’s name starts with NSMutable, and you use the copy declaration attribute, then the code that is synthesized for you is not correct. Because it uses copy, not mutableCopy, to do the copy during assignment, the value will not be mutable.

Here’s a demonstration,

@interface Gotcha : NSObject {
	NSMutableString *mutableString;
}
@property (copy) NSMutableString *mutableString;
@end
@implementation Gotcha
@synthesize mutableString;
@end

... Gotcha *x = [[[Gotcha alloc] init] autorelease]; x.mutableString = [NSMutableString stringWithString:@"I am mutable."]; [x.mutableString appendString:@" Look at me change."];

It crashes with the message,

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Attempt to mutate immutable object with appendString:’

copy vs mutableCopy

The copy method returns an immutable copy of an object, even if the object is mutable. Eg the copy of an NSMutableString is an immutable NSString.

The mutableCopy method returns a mutable copy of an object, even if the object is not mutable. Eg., the mutableCopy of an NSString is an NSMutableString object.

@synthesize always uses copy in the setters it generates. That means an immutable copy will always be stored, even if an NSMutable object is given.

Workarounds

Apple says, ” …In this situation, you have to provide your own implementation of the setter method..” (To me, this isn’t as satisfying of an answer as a mutablecopy attribute. But it’s what Apple has chosen, so all we can do is file enhancement requests and trust their reasoning).

Another workaround is to make any property that is a mutable value readonly. If something is mutable, you can change it’s contents directly, so there is rarely a need to set it. For example, with the Gotcha object, it’s just as easy to say

[x.mutableString setString:@"New String"];

as

x.mutableString = [NSMutableString stringWithString:@"New String"];

Finally, you might consider using an immutable readwrite property. In my experience, immutable objects are generally safer, and often faster (I owe you an article on this, but there are plenty of articles on the benefits of immutability). I know this sounds like a smart-ass suggestion, and it won’t be a good answer much of the time. But it’s surprising how often things turn out not to need mutability once a design matures. Since reducing the mutability of an object often improves it, and it does work around the problem, it’s worth at least considering this solution.

Why not Just Use retain?

Changing the copy to retain well let you assign a mutable object, but I do not like the idea. My article, Prefer copy Over retain explains in detail. My biggest worry is aliasing,

NSMutableString *aLocalString = [NSMutableString string];
x.mutableString = aLocalString;
[x doSomething];
//aLocalString might have been changed by doSomething!
//
// 300 lines later...
//
[aLocalString appendString:@" now with more bugs!"];
//x has been changed too!

Using retain with NSMutable objects is asking for bugs.

March 13, 2009

Reasons to WANT to Design For Accessibility

Accessibility is too often seen as a chore. But there are many reasons to be excited about making things usable for everyone.

It Just Feels Good

I know it’s cliché, but helping people does feel good. Making your website work with screen-readers is not the same as volunteering your time to read for the blind and dyslexic. But it still helps…

More cynically, accessibility means your work reaches more people. Even if it’s just an extra 0.6%, it still feels good to know you are having a bigger impact.

We Are All Impaired

As Keith Lang points out, “we are all impaired to some amount (or sometimes)”. Everyone is “deaf” in a library, because they can’t use speakers there. Similarly, if you try showing a video on your phone to a dozen people, many of them will be “blind”, because they can’t see the tiny screen.

Consequently, accessibility means designing for everyone, not just a disabled super-minority.

Accessible Design is Better Design

Usability improves when accessibility is improved. For example, a bus announcing stops with speakers and signs means you can keep listening to your iPod, or looking at your book, and still catch your stop. It makes buses easier to ride.

Maximally accessible design engages multiple senses. Done well that means a more powerful experience.

Early Warning

The flip-side of accessibility improving usability is that bad design is hard to make accessible. How easy it is to make something comply with accessibility guidelines is a test of the soundness of the design.

I don’t care about accessibility. Because when Web design is practiced as a craft, and not a consolation, accessibility comes for free.

Jeffrey Veen

Accessibility compliance should be like running a spellcheck — something quick and easy that catches mistakes. When it’s not, it’s a warning that something is fundamentally wrong. That’s never fun, but the sooner a mistake is caught, the cheaper it is to correct it.

Challenge the Establishment

Accessibility might be the best “excuse” you’ll ever get to do fundamental UX research.

I think for people who are interested in user interface disability research is another area that gets you out of the Mcluhan fishbowl(??) and into a context where you have to go back to first principles and re-examine things. So I think the future there is very bright but we need more people working on it.

–Alan Kay, Doing With Images Makes Symbols

If anybody knows what he meant by what I heard as “Mcluhan fishbowl” please let me know!

Technology is Cool

Accessible design makes content easier for machines and programmers to deal with. This makes the future possible. For example, embedding a transcript in a video means that the video’s contents can be indexed by google, or automatically translated, etc.

BUt the really exciting stuff hasn’t happened yet.

Accessibility research is going to be a huge part of what advances the state of the art in Augmented Reality and cybernetics/transhumanism. The common theme is mapping data from one sense to another, or into a form that computers (eg. screen readers today) can process.

Why do You Like it?

I’d love to know what makes you passionate about accessibility. For me it’s that it feels right, and as a programmer, I am very excited about what it enables.

A Chair for Design

Filed under: Design,Quotes | , ,
― Vincent Gable on March 13, 2009

Alan Kay explained why he liked beanbag chairs at PARC,

And one of the reasons we used them was that we discovered it was almost impossible to leap to your feat to denounce someone once you had sat in a bean bag chair, because you tended to sink into it further and further. So it had a way of relaxing people and it was very good for design.

From Doing With Images Makes Symbols

What seating arrangement do you think works best for creativity, both individual and group? Personally I like pacing when I’m thinking alone.

(Always) Showing a Window on Application Switch

Filed under: Cocoa,MacOSX,Objective-C,Programming | , ,
― Vincent Gable on March 13, 2009

Keith Lang said all Mac applications should show a window when you switch to them via command-tab or gestures. I agree. I do think it is best to show nothing when the last window is closed; otherwise closing a window might mean more stuff in your face, not less. But when context-switching back into an application I can’t think of a good reason why applications shouldn’t have something up that you can interact with right now.1

This is the behavior you get when switching between applications by clicking their icons in the dock. It’s unfortunate that you have to do more work for your application to behave consistently no matter how it’s switched-to. Here’s how I’ve done this in IMLocation,

In my NSApplication delegate I implemented - (void)applicationDidBecomeActive:(NSNotification *)aNotification to check if no windows were visible, and if so, put something up. Here’s the exact code I use, replace editCurrentLocation: with what’s right for you:

- (void)applicationDidBecomeActive:(NSNotification *)aNotification
{
	[self displayLocationWindowIfNoWindowIsOpen];
}
- (void) displayLocationWindowIfNoWindowIsOpen
{
	NSArray *visibleWindows = [[NSApp windows] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"isVisible == YES"]];
	if(IsEmpty(visibleWindows))
		[self editCurrentLocation:nil];
}


1Xcode, doesn’t put up anything when you click on it’s icon and you have turned off the “Getting Started” splash screen. This makes a bit of sense, because Xcode is a project editor, not a document editor. Projects are collections of many files, and having an “untitled” default one does not make sense. But by default Xcode shows a window, the splash screen. And there is an argument that it should show an empty file, like an Emacs “scratch buffer”.

March 10, 2009

Dashboards on Steering Wheels Are Complicated

Filed under: Design,Quotes,Usability | ,
― Vincent Gable on March 10, 2009

Given that all 11 F1 teams have converged on a remarkably similar UI (for a dashboard on a steering wheel), independently, you would think that (the style) was a rational design, however its complexity possibly caused Lewis Hamilton the 2007 F1 championship, when he accidentally pressed the neutral button …

825b387026c6c81ef5a96970ccd12ee8-orig.png

What is clear is that there is no clear accentuation of features (color, size) by how often the are used, merely by position. Even if drivers like Hamilton are experts and fully familiar with the UI, there is a tiny percentage chance of error. Our guess is that this trend in car UI would be a mistake if it filters through to everyday cars, and that F1 cars will revert to a more simple UI over time.

oobject.com (article includes a gallery of F1 steering wheels)

Certainly I have made mistakes with traditionally mounted dashboards in every car I have owned. But the mistakes haven’t significantly impaired by driving. Accidentally turning on the air conditioner or radio aren’t a big deal — even with my old Volvo that couldn’t accelerate as well with the AC on.

Older Posts »

Powered by WordPress