February 26, 2009

Radio-button behavior for table rows

One thing missing from the iPhones UI kit is a plain old radio button. There are some controls that kind of give you the exclusive selection behavior, like a tab bar or a segment control, but there is nothing like a typical RadioButton widget. The closest you can probably get using the standard UIKit framework is a table. Tables have rudimentary support for radio button behavior. When using the standard UITableCell class, it has provisions for setting the accessory type of a row to a checkmark. You have probably seen this technique in the calendar app while editing an event alert. Your choices are presented like this:
Unfortunately, this is pure visual asthetics; you still have to manage the exclusive behavior in your code. The document "Table View Programming Guide for iPhone OS " has a good example of how to implement both exclusive and inclusive selections in chapter 7 that makes use of the checkmark accessory. I won't repeat that code here, but in a nutshell, this example code handles the message tableView:didSelectRowAtIndexPath:, and what it does (for the exclusive selection behavior) is find the previously selected cell, clear it's accessory checkmark, and put the checkmark on the current cell. It's a little cumbersome, but it works. This is all fine, but what if you didn't want to use the checkmark accessory? I have an application where I need to use the disclosure button accessory, so I needed to implement the checkmark somewhere else. The solution I chose was to create my own checkmark icon and place that in the image portion of the standard cell, over on the left hand side of the cell. I quickly discovered, though, that you can't use the same technique as in the above document. If you change the image of a cell, the changes will not be seen. For some reason, changing the accessory type of a cell is rendered immediately, but not so for the image. The only way I could get the image change to be reflected is to call reloadData: on the table view. After I did that, everything worked. However, I took this opportunity to clean up the clunky code from the example. Instead of finding my old cell, all I do in tableView:didSelectRowAtIndexPath: is set the current active row in our data and call reloadData:. The real work was moved over to the table:cellForRowAtIndexPath: method, which sets the image for each cell according to the active row. First we must handle the row selection. The instance variable activeRow is simply an integer of the currently selected row.
- (void)
tableView:(UITableView *) aTableView didSelectRowAtIndexPath:(NSIndexPath *) indexPath
{
 [aTableView deselectRowAtIndexPath:indexPath animated:NO];

 if(indexPath.row != activeRow) {
    // reset the active account
    activeRow = indexPath.row;

    // tell the table to rebuild itself
    [aTableView reloadData];
 }
}
Next we handle the actual image setting:
- (UITableViewCell *)
tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:@"Cell"];

 if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];

    // set up the cell properties that are the same for all cells on this table
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
 }

 // get our text for the row
 cell.text = [self.data forRow:indexPath.row];

 if(indexPath.row == activeRow) {
    cell.image = checkedImage;
 }
 else {
    cell.image = uncheckedImage;
 }

 return cell;
}
After we get a cell to work with, I compare the row with the active row. If it is a match, I use the checked image. If not I use the unchecked image. Here is the final output:

February 23, 2009

Tab Bar Icons (Part 1)

Tab bars are for toggling between application views. This is a common controller on the screen-constrained iPhone. Not to be confused with toolbars, tab bars are the black bars at the bottom of the screen with gray unselected icons and one blue selected icon. You see tab bars in the phone and ipod and YouTube apps, among others. Here is an example, from the ipod app:
When you are creating a tab bar for your own application, you face the problem of providing the icons. You have several options here. Your first option is to use one of Apple's system icons. Like the navigation bar, you have access to some of Apple's system icons, and they even encourage you to use them. Unfortunately, there are a couple caveats with using these. First, the list is pretty skimpy. Second, the icons include the text as well. You cannot set the image and the text separately; it's both or nothing. Here is what is offered:
icon text enum
More UITabBarSystemItemMore
Favorites UITabBarSystemItemFavorites
Featured UITabBarSystemItemFeatured
Top 25 UITabBarSystemItemTopRated
Recent UITabBarSystemItemRecents
Contacts UITabBarSystemItemContacts
History UITabBarSystemItemHistory
Bookmarks UITabBarSystemItemBookmarks
Search UITabBarSystemItemSearch
Updates UITabBarSystemItemDownloads
Most Recent UITabBarSystemItemMostRecent
Most Viewed UITabBarSystemItemMostViewed
If you can make use of them, you access them via an enum for each defined in the UITabBarItem class. Here is how you would programatically set your tab bar image to the magnifying glass:
self.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemSearch tag:0];
You execute this in your UIViewController subclass that you are putting into the tab bar. This is best done in your view controller's initializer method:
- (id) init
{
self.title = "search";
self.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemSearch tag:0];
return self;
}  
If the system icons don't meet your needs, some people have suggested doing a screen capture of an app that has an icon you like. Ignoring the legalities of this, this may not give you good results because Cocoa-Touch has already applied affects to the icons. Your next option would be to search for some free or pay-for icons. I noticed many freelance graphics designers putting their shingle up and offering their services. I didn't look long, but I did not find any suitable, free icons for iPhone tab bars. This leaves you one last option: create your own. So the first questions that come up are:
  1. what format?
  2. what size?
  3. what colors?
After researching these questions, I found some conflicting answers and lots of confusion among the iPhone developer community. I will try to summarize and disperse the clouds. For format, this is pretty well agreed upon to be PNG, which is the image format of choice on the iPhone. You're not limited to this format, but PNG is the recommended format and gives best performance. The background should be transparent, else your icon will be a plain square. The size issue is a bit more contentious. I saw reports of sizes ranging from 20 x 20 all the way up to 57 x 57. Most people don't differentiate between pixel or point sizes, and they are different. Here is what Apple says in the reference documentation for the UITabBarItem:
If this image is too large to fit on the tab bar, it is scaled to fit. The size of an [sic] tab bar image is typically 30 x 30 points.
Note it doesn't say what the max size is before it gets scaled. One poster thought the max size was around 48 x 32 before scaling happens. But if Apple doesn't publish this information explicitly, I would hesitate to use it. You could explore yourself to find out what the max is, but obviously Apple would like to retain some latitude in this area to possibly change it in future firmware releases. I believe 30 x 30 is a safe size that will give you the best look. There also seems to be a great deal of confusion regarding colors. From my research, colors are basically ignored. Here is what the Apple document "View Controller Programming" has to say about it:
The unselected and selected images displayed by the tab bar are derived from the images that you set. The alpha values in the source image are used to create the other images—opaque values are ignored.
In other words, Cocoa Touch will create new images from your source images, using alpha values only. Alpha, in the PNG world, is the degree of a pixel's opacity. Maximum alpha values denote a completely opaque pixels. In the example below this quoted text, they have an example source image and the resulting unselected and selected icons. Color is irrelevant. In part 2 of this article, I will discuss various tools used to compose icons, specifically how to create tab bar icons.

February 19, 2009

Objective-C Initializer Patterns

Creating objects in Objective-C is a two step process: you first allocate the space for the object, then you initialize it. In C++, the act of allocating (new) an object automatically calls the object's constructor, but it's basically the same two steps under the covers. However, the similarities end there. Objective-C initializer methods are different from C++ constructors. Those coming over from C++ might struggle a bit with them, so this article will attempt to bring forth these differences and discuss some common patterns.

Names

The most obvious difference are the names. The name of C++ constructors must be the same as the class name. Objective-C initializers, by convention, start with the prefix "init". However, since these are simply methods, this naming is purely by convention. You could call your initializer "jimmyJoeBob" if you wanted, but the pattern is to use "init" as the prefix, so "initJimmyJoeBob" would be OK.

Return Types

This one recently burned me. C++ constructors don't really have a return type, since they are not really methods. If it had to have a return type, you would assume it was a pointer to the class it is constructing. Not so in Objective-C. Take this blunder for instance: We have a base class:
@interface Base
{}
- (Base*) init;
@end
And we have a child class:
@interface Child : Base
{}
- (Child*) init;
@end
Each has an initializer. Neither is named "jimmyJoeBob", so we're OK there, but do you see the problem? Sure, this is a stupid mistake, but I believe many C++ converts will stumble into this: Class initializer methods must have a return type of id. If you fail to do this, and you are overriding a parent's initializer, you get a cryptic message from the compiler saying "warning: assignment from distinct objective-c type". This is because your override did not completely override; the return types don't match. Making all the initializers return id gets around this problem.

Return Values

All your initializers typically return "self". You might think that it would be nice if they did that automatically, but remember: these are really methods, not constructors. Initializers may return something different than what was allocated. What they return needs to be the same type as self, but it could be a different instance. One poor example would be if the class maintained a pool of already-allocated and initialized objects of itself. If the caller was initializing an object exactly the same as an object already in the pool, the initializer may deallocate itself and return the pooled instance instead. Initializers can also return nil if there was an error. C++ constructors can't return anything. The best they can do is set a flag, or worse, throw an exception. Because of these capabilities of the initializers, you should never use code like this:
id object = [MyClass alloc];
[object init];
[object doSomething];
The reason is the init method could have returned a different object, or nil, but this code would have missed it. The pattern you really should use is this:
id object = [[MyClass alloc] init];
And since the initializer could return nil, it might best to check the value before using it.

Automatic Memory Clearing

One really nice thing about Objective-C is that the allocate will fill the instance data with all 0's. As practical as this seems, C++ doesn't enjoy this luxury, and it must tediously initialize every instance variable; otherwise their values are random. This behavior makes most initializers unnecessary.

Super Initializers

Just like in C++, Objective-C initializers should explicitly call the appropriate initializer of its parent class. This is done via the "super" pointer. But wait! Since initializers can return nil or something entirely different, your child class initializer needs to be aware of that. The pattern here is to reassign self to what comes back from the super initializer, just in case it returned something else. And check for nil for good measure:
- (id) init {
  self = [super init];
  if(self) {
     ...
  }

  return self;
}

Returning Nil

When there is some error in the initializer, and your only recourse is to return nil, you have to be careful about creating a memory leak. If you simply returned nil, then the original pointer to the object is lost, which results in a memory leak. You should release yourself first before returning nil. The one who is returning nil is the one who releases. If you get back nil from a super initializer, you can assume it has already released. The release should be done at the first point of failure. Example:
- (id) init {
  if(someKindOfError) {
     [self release];
     return nil;
  }
}

Avoid Accessor Methods

It is generally recommended to avoid using property setters in initializers, due to possible side-effects. In other words, don't set properties with "self.propname = something". Use the instance variable directly: "propname = something;"

This can only apply to your own instance variables; for initializing instance variables on other objects, you may have only the accessor methods.

Convenience Constructors

There is one last pattern to consider for initializers. Some Cocoa classes have what are called convenience constructors. You might also call these factory methods. These are static (class-based) methods that allocate and initialize an object for you. Examples of these can be found in the NSString and NSArray classes. One thing to be aware of with convenience constructors: Unlike using alloc/init, the retain count of what is returned is not automatically set to 1. You need to retain any pointer you get back from a convenience constructor. I'm sure there is some valid use case as to why we have this inconsistent behavior, but I don't know what it is.

Example

Now we'll summarize all this with an example that demonstrates most of the patterns mentioned above. The interesting bits will be preceded by a red number and explained afterward:
- 1(id) 2initWithFile:(NSString*) filename {
3self = [super init];
4if(self) {
 if(filename == nil) {
     5[self release];
     return nil;
 } else {
     6m_filename = filename;
     [m_filename retain];
 }
}

7return self
}
  1. Initializers are instance methods that always return id
  2. By convention, initializers begin with the prefix "init"
  3. Always call your super initializer, and reassign self to that return
  4. Be sure to check the return value from your super, since it may return nil
  5. If you have an error release yourself first, then return nil
  6. Access your instance variables directly, and retain manually
  7. Return self

February 17, 2009

Property Pitfalls and Patterns

Properties are a handy, if not a cumbersome, addition to Objective-C 2.0. Although they add a good deal of convenience, you must never forget what is happening under the covers, else you could end up with problems and confusion. The problem I blindly walked into was not considering the automatic retain done when using the setter. Consider this statement:
self.name = input_name;
This actually invokes a setter that the compiler has synthesized for you. If you declared the property with the "retain" attribute, as in this:
@property (nonatomic,retain) NSString* name;
then what the above assignment will do is:
  1. release whatever name is pointing to
  2. set the new value
  3. retain the new value (take ownership)
This shortcut is extremely handy; however, it's easy to forget that there are some cases where you are already the owner of an object, so the retain is redundant and will cause a memory leak:
self.name = [[NSString alloc] initWithString:input_name];
When you alloc an object, the retain count is already set to one. When you assign this to your property, the setter will bump up the retain count again. The retain count of self.name is now 2. Thus, you have a memory leak. [update date:@"Feb 19, 2009"]; It should be noted that the line above is different than this line:
name = [[NSString alloc] initWithString:input_name];
This form is accessing the instance variable directly, whereas the self.name form is invoking the property's setName: method. This distinction is important because when you skirt around the setter, you don't get the 3 little "side-effects" mentioned above. This can be both useful and dangerous. I recommend NOT using the instance variable directly if it is a property, unless you are in an initializer. It is just too easy to get things wrong; if you assign directly to the instance variable and it already has something assigned to it, you get a memory leak. It is best to be consistent with how you use your properties. [endupdate]; There are a couple solutions I have seen so far, but I don't think any of them are very pretty. One common trick is to autorelease the return from init. This way, the retain count will still be 2, but the next time the autorelease pool is emptied, the redundant reference is cleaned up:
self.name = [[[NSString alloc] initWithString:input_name] autorelease];
This violates the general rule of avoiding autorelease as much as possible. Autoreleasing will release the memory (at some point), but you have no control when that actually happens. Memory could get bloated or even run out before it does happen. When coding on a limited resource device like the iPhone, I think this is a good rule to follow. Another solution is simply to release after the assignment:
self.name = [[NSString alloc] initWithString:input_name];
[self.name release];
But this is non intuitive and can be confusing. A clumsier but cleaner way would be to use a local variable:
NSString* temp = [[NSString alloc] initWithString:input_name];
self.name = temp;
[temp release];
Any other ideas on how best to do this? There is another pattern in common use that I missed in my first applications. It concerns dealloc and properties. Here is what I used to do:
- (void) dealloc
{
  [property1 release];
  [property2 release];

  [super dealloc];
}
Seems perfectly reasonable, and I believe in most cases, this is fine. However, the preferred mechanism for releasing properties is to assign nil to them:
- (void) dealloc
{
   self.property1 = nil;
   self.property2 = nil;

   [super dealloc];
}
So what's the difference? I'm still searching for the definitive answer, but I believe this is preferred because it releases the property and sets it to nil. How? At first glance, this looks like a memory leak. But remember the steps that synthesized setters do for you: 1) release the old value, 2) assign the new value, then 3) retain the new value. In this case, you can't retain nil, so the 3rd step is a no-op. This is a common technique in C++ destructors, which prevents a deallocated pointer from being used later on. This syntax is not intuitive, though, and you have to understand what's going on in the setter.

February 13, 2009

Private Methods in Objective-C

Most mainstream OO languages (C++, Java) support the notion of private, protected, and public class members. I've debated for years whether these protection attributes are really worthwhile, but it seems the designers of Objective-C felt protection for methods was not necessary. While you can add the various protection attributes to class and instance fields, you cannot do the same for methods.

There are several tricks you can employ, but I will present here the most straightforward and simplest approach. This trick uses the concept of class extensions, a bizarre facility that allows you to extend another class with replacement or additional methods. This technique is also sanctioned by the Apple Objective-C 2.0 Programming Language document (The Objective-C 2.0 Programming Language). To add a private method to your class, you extend your own class within your implementation (.m) file. This way, clients of your interface (.h) file do not see or know about your methods. For example:

// .h file to declare our class
@interface MyClass

// this is a public method
- (void) sayHi;
@end

You'll notice in the header file, which is imported by users of your MyClass, has no mention of a private method. It is the implementation file where we put it:
// .m file to define our class
// but first let's extend our class with a private method
@interface MyClass ()

// this is a private method
- (void) tellSecret;
@end

// now we implement everything
@implementation MyClass

// the public method
- (void) sayHi
{
  NSLog(@"Hello everyone!");
}

// the private method
- (void) tellSecret
{
  NSLog(@"Psst, ...");
}

@end

Welcome iPhone developers!

Hello everyone. I have recently jumped on the bandwagon to develop applications for the iPhone and iPod Touch. It has certainly been a journey of discovery for an old Java/C++/Python programmer to delve into Objective-C and Cocoa. This blog serves as a travelogue of that journey, disseminating tidbits of useful stuff I learned along the way. This information will most likely be useful to those who, like me, are just getting your feet wet in this strange but wonderful world of Cocoa programming. Come back often to see code snippets, tips, and tutorials. Also, announcements for our released iPhone apps will be made here. Have a wonderful voyage!