Unprofessional Documentation

Apple has one glaring omission in its API documentation for developers: memory management is covered truly, abysmally badly, to the point that it’s just terribly unprofessional. Here’s an example I was shown today:

- (void) beginRequest:(NSString*)action {
  query = [NSMutableString stringWithFormat:@"%@/%@?",SERVICE_URL, action];
}

The problem? The stringWithFormat message returns an “autoreleased” object; that is, once the main run loop drains the global autorelease pool, the object is deallocated. What the code should have done is this:

- (void) beginRequest:(NSString*)action {
  query = [[NSMutableString stringWithFormat:@"%@/%@?",SERVICE_URL, action]
      retain];
}

Why is that a problem? Because you don’t know.

Apple does have some rules on when to use retain and when not to, but they’re incredibly well hidden in the only sensible documentation Apple has on memory management:

  • You own any object you create.
  • You can take ownership of an object using retain.
  • You must relinquish ownership of objects you own when you’re finished with them.
  • You must not relinquish ownership of an object you do not own.

And how do you know whether you own an object because you created it?

You “create” an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).

Yes, that’s right. You know by convention, which is documented in an ancilliary document, which, crucially, is nowhere referenced in the actual API documentation.

Might as well not document it, then.

Incidentally, why a function that returns a new string object is not considered to “create” it and therefore requires you to use retain is a complete mystery, too. But let’s not go there, asking questions like that is opening Pandora’s box1

  1. For those of you who were unaware of the story, you’re welcome. For what, you say? For spending hours clicking through Wikipedia articles, of course! []

  • Andy

    Interesting. Even though I’m not a programmer, I get the frustration you’re driving at. I dunno, Apple to me are just severely overrated in everything they do, from hardware to software to user experience. They look great on the outside and work well enough, but really they come with a host of tradeoffs and when something doesn’t work it’s all your fault anyway. Or so they try and convince you. Why are they so great again?

    Be interesting to see if there is a follow up on this in the days to come. :-)

    Andy.

    • http://www.unwesen.de/ unwesen

      I should stress that Apple aren’t necessarily worse in this than other companies are in documenting APIs, or than FOSS projects are. Though some FOSS projects have exceptional documentation, which I haven’t seen for any proprietary software.

      What gets me about this particular oversight is that documenting ownership of memory well is crucial in avoiding a huge variety of bugs, both memory leaks and crashes. Things get especially bad when there’s multiple threads involved. To treat this one aspect of documenting APIs so flippantly is practically to invite bugs.

      There’s stuff in APIs that needn’t be documented well, like well-named, obvious function parameters. int open(char const * path, int flags) is one such example: you need to document which flags exist, but the “path” parameter is obvious.

      Interestingly enough, I’ve seen more coding standards that demand every parameter be documented than those that demand memory ownership is. Probably because the former can more easily be verified by automated tools…