Question

One feature of Java that I really like is autoboxing, in which the compiler automatically converts between primitives and their wrapper classes.

I'm writing a Core Data application in Objective-C/Cocoa, and I'm finding it frustrating to deal with my integer attributes programmatically. Here's why:

//img is a managed object that I have fetched

NSString* filename = [NSString stringWithFormat:@"image%d.png", [[img valueForKey:@"imageID"] intValue]];  

If I happen to forget the intValue message, which I sometimes do, then the int that gets passed to stringWithFormat: is actually the pointer value.

The problem is that this happens totally silently--no compiler error or warning. Sometimes I'll spend way too long debugging when this silly, stupid thing is the problem.

Is there a way to change my programming style or my compiler settings to prevent me from getting caught in that trap?

Edit: I wasn't clear about the fact that the above example is just one of many places where I run into trouble. Here's another hypothetical example that doesn't have to do with strings:

Entity CollegeClass has two integer attributes: courseNumber and enrollmentLimit. Let's say I want to compare course numbers:

//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
    NSLog(@"undergraduate class");
}

Or similarly, suppose I want to compute the average enrollment limit for all the classes in the CS department.

Was it helpful?

Solution

… suppose I want to compute the average enrollment limit for all the classes in the CS department.

This is easy to do with NSArray's and NSSet's @avg operator. Of course, that will return an NSNumber, which puts you back in problem #2:

Let's say I want to compare course numbers:

//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
    NSLog(@"undergraduate class");
}

I assume you mean that the problem you risk is omitting the intValue message, thereby comparing the NSNumber object's id to the int.

The compiler offers a warning for such comparisons. In Xcode, add -Wextra to your “Other C Flags” build setting. For more warning options, see the full list of GCC warnings.

OTHER TIPS

You can use %@ to convert a NSNumber directly to a string instead of the %d.

It will actually take any NSObject based class and convert it to a string I believe.

This is only applicable when dealing with Core Data, but if you use MOGenerator to generate classes for your Core Data objects (which I'd recommend doing anyway), you can then use -[propertyName]Value methods to directly access the correct value for properties which return NSNumbers:

// These two methods are identical when called on a class 
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];

Turn on the “Typecheck calls to printf/scanf” warning, if it isn't on already. This doesn't currently help with NS/CFString formatting, but I've filed a Radar enhancement request (x-radar://problem/7375186) for that. You're welcome to file your own, of course.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top