views:

2229

answers:

3

I like to create an instance of a custom class by passing it a value that upon init will help set it up. I've overridden init and actually changed it to:

- (id)initWithValue:(NSInteger *)initialValue;

i'd like to store this value in a property of the instantiated object and use the value to generate the filename of a UIImage that will be associated with it.

My question is how best to go about this in Cocoa/Obj-C. is an NSInteger the best parameter for my needs or would an NSString be better? Or is there another design pattern? I'm not familiar with all the creative methods available to help in this situation. Assume my class properties are:

@interface MyView : UIView {
UIImage *image;
NSInteger value;

If I stick with the NSInteger as a parameter I can easily assign value to it. but then would need to generate "image12.png" from that value (assume NSInteger = 12) to set up my UIImage. Something like "image"+initialValue+".png". Which I believe is verbosely expressed in Obj-C as:

NSString *myValue = @"image";
[myValue stringByAppendingString:[initialValue stringValue]]; //NSInteger may not respond to stringValue?!?
[myValue stringByAppendingString:@".png"]

This is where my understanding of Obj-C breaks down. Feels to me like this should be easier but I'm still confused.

Now if initialValue was an NSString with the value of @"12" maybe it is? then self.value = [initialValue integerValue];

and I could build image with multiple stringByAppendingString calls. Just seems tedious for something so simple in other languages.

What's best way to handle something like this?

+5  A: 

Your init method looks fine, and if you're only dealing with integer values, you do want to use NSInteger as opposed to NSString or even NSNumber. The one thing you might want to change is the parameter you're passing should be (NSInteger), not (NSInteger *) - an NSInteger is not an object, but in Objective-C is a primitive type similar to int.

You can build the image name by using NSString's stringWithFormat: selector, as such:

NSInteger myInteger = 12;
NSString *imageString = [NSString stringWithFormat:@"image%d.png", myInteger];
Tim
+2  A: 

Just to expand on what Tim mentioned, an NSInteger is actually just a #define. On 32-bit architectures, it's equivalent to an int and on 64-bit architectures it's a long.

If you need to treat an integer as an object (to put it in an NSDictionary, for instance), you can wrap it in an instance of NSNumber using numberWithInteger:.

Hope that helps!

Ben Gotow
Good point about wrapping an NSInteger in an NSNumber!
Tim
There's actually a numberWithInteger: method since NSInteger appeared with 10.5, you'll see similar methods in places like NSUserDefaults too.
Marc Charbonneau
thanks Marc - I updated the post
Ben Gotow
A: 

One other thing to keep in mind though is that when you're dealing with paths NSString gives you stringByAppendingPathExtension: and stringByAppendingPathComponent:, both of which handle things like trailing slashes better than if you just use stringByAppendingString:.

If you describe a little more about what this object does and what kind of images it's loading I might be able to offer some advice if I can think of a better way of creating the filenames, instead of just passing a number around.

Marc Charbonneau
I'm just pulling the images from the bundle so don't think I need to worry about pathnames in this case...but now I understand why those Path methods are there. I was wondering why it wasn't preferable just to spell out the pathname as a string. Interesting. thx!
Meltemi