As Jason wrote you should use stringWithFormat: to format strings with printf like syntax.
-(NSString*)description;
{
  return [NSString stringWithFormat:@"Name: %@ Mass: %d", bodyName, bodyMass];
}
To avoid writing this over and over again for many classes you could add a category on NSObject that allows you to inspect instance variables easily. This will be bad performance, but works for debugging purposes.
@implementation NSObject (IvarDictionary)
-(NSDictionary*)dictionaryWithIvars;
{
  NSMutableDictionary* dict = [NSMutableDictionary dictionary];
  unsigned int ivarCount;
  Ivar* ivars = class_copyIvarList([self class], &ivarCount);
  for (int i = 0; i < ivarCount; i++) {
    NSString* name = [NSString stringWithCString:ivar_getName(ivars[i])
                                        encoding:NSASCIIStringEncoding];
    id value = [self valueForKey:name];
    if (value == nil) {
      value = [NSNull null];
    }
    [dict setObject:value forKey:name];
  }
  free(vars);
  return [[dict copy] autorelease]; 
}
@end
With this in place implementing description is also a piece of cake:
-(NSString*)description;
{
  return [[self dictionaryWithIvars] description];
}
Do not add this description as a category on NSObject, or you might end up with infinite recursions.