Binary Lion Studios

I code for fun and for food.

Objective-C category gotcha

Say you have a simple User object that contains a Name object with two properties: first and last. It might look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@implementation User
-(Name *)name {
  return _name;
}
@end

@implementation Name
-(NSString *)first {
  return _first;
}

-(NSString *)last {
  return _last;
}
@end

Now you want to create a category that uses some mock data for the first and last name.

1
2
3
4
5
6
7
8
9
@implementation Name (MockData)
-(NSString *)first {
  return @"Test";
}

-(NSString *)last {
  return @"User";
}
@end

Now in a view controller, you try to use the category.

1
2
3
4
5
6
7
8
9
10
@implementation MyViewController
-(void)doSomethingAwesome {
  User *user = [[User alloc] init];

  // output - Your name is:
  NSLog(@"Your name is: %@ %@", user.name.first, user.name.last);

  [user release];
}
@end

The NSLog statement above will output Your name is:. Why does it not use your category? The reason makes sense now, but was a bit confusing at first. In the example above, the name property on the User object in the view controller is actually nil. So when you ask for the first property on the Name object, it actually sends the message to a nil pointer, which is not a Name object. Thus, it never hits your category.

The solution is to either instantiate an empty Name object when you create a user, or change your category to extend the User object and return a populated Name object when the name property is accessed.