views:

252

answers:

2

Lets say i have a little bit of code I would like to repeat a number of times. How should I best include this in my iPhone app to only have to write this once?

Its a typical TableView Controller App.

//Set Icon
        UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(30,25,20,20)];
        imgView.image = [UIImage imageNamed:@"ico-date.png"];
        [self.view addSubview:imgView];

Regards

A: 

There are a couple of ways

  • Sub-classing

Stick this in a base class and just inherit from that, no muss no fuss

  • Shared Method

Parametrize the use of self and instead pass the UIView* as a parameter you want to be doing the adding to. Then stick that method in a single class accessible from all over and call it only when appropriate.

  • Category

Create a category like UIImageView+Icon and put the code there, then you can shorten it to something like [self.view addSubview:[UIImageView icon:@"ico-date.png"]]

slf
+3  A: 

Your options:

1) Create a static C function to do it

static UIImageView* myfunc(CGFloat x, CGFloat y, CGFloat w, CGFloat h,
  NSString* name, NSString* type, UIView* parent) {
    UIImageView *imgView = [[UIImageView alloc] initWithFrame:
      CGRectMake(x,y,w,h)]; 
    imgView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
      pathForResource:name ofType:type]];
    [self.view addSubView:imgView];
    [imgView release];
    return imgView;
}

2) Create a C macro

#define CREATE_ICON_VIEW(parent,x,y,w,h,name) \
  ...

3) Create an Objective-C static method

// in @interface section
+ (UIImageView*)addIconWithRect:(CGRect)rect name:(NSString*)name
  type:(NSString*)type toView:(UIView*)view;

// in @implementation section
+ (UIImageView*)addIconWithRect:(CGRect)rect name:(NSString*)name
  type:(NSString*)type toView:(UIView*)view {
  UIImageView *imgView = [[UIImageView alloc] initWithFrame:rect];
  imgView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
    pathForResource:name ofType:type]];
  [self.view addSubView:imgView];     }
  [imgView release];
  return imgView;
}

// somewhere in app code
[MyClass addIconWithRect:CGMakeRect(0,0,32,32) name:@"ico-date"
  type:@"png" toView:parentView];

4) Create an Objective-C category on UIImage or UIImageView

5) Create a method on the view that is to have a UIImageView added

- (void)addIconWithRect:(CGRect)rect name:(NSString*)name type:(NSString*)type {
  UIImageView *imgView = [[UIImageView alloc] initWithFrame:rect];
  imgView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
    pathForResource:name ofType:type]];
  [self.view addSubView:imgView];     }
  [imgView release];
  return imgView;
}

6) Create a Helper class

Like option (3) but put the static methods in a separate class that's just for utility methods for repeated sections of code eg call the helper class "UIUtils".

7) Use a C inline function

static inline UIImageView* myfunc(CGFloat x, CGFloat y, CGFloat w, CGFloat h,
  NSString* name, NSString* type, UIView* parent) {
    UIImageView *imgView = [[UIImageView alloc] initWithFrame:
      CGRectMake(x,y,w,h)]; 
    imgView.image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
      pathForResource:name ofType:type]];
    [self.view addSubview:imgView]; 
    [imgView release];
    return imgView;
}

8) Use a loop to execute the same code repeatedly

9) Use an ordinary non-static Objective-C method

Personally I would go for none of these for your particular example and just write it out long-hand, unless it is repeated more than ten times in a file in which case I might go for (3). If its used in a lot of files I might go for (6).

Edit: Expanded descriptions for (3) and (6) and note about when I use (6).

Edit: Added options 8 & 9. Fixed memory leaks and some mistakes.

Edit: Updated code to use imageWithContentsOfFile instead of imageNamed.

martinr
You can pass a `CGRect` in the C functions.
KennyTM
on the 3) Create an Objective-C static method, where does the first bit go, appDelegate? and then what do i put in for 'MyClass'?
norskben
It's a static method so it's eg "XYZAppDelegate" (the *class name*) NOT eg "appDelegate" the variable name where I wrote MyClass.
martinr
but if i was implementing #3, 1) Where do i paste the above method, will it run from myAppAppDelegate and then i can call it from wherever using "[MyClass addIconWithRect:CGMakeRect(0,0,32,32) name:@"ico-date.png" toView:parentView];"??
norskben
The (+) symbol means static method. All methods, whether static or not, must be both declared in an @interface section, and also implemented in an @implementation section. If you're calling it from lots of places consider placing it in its own separate class, (which is what I mean by "making a Helper class") and calling that UIUtils or something like that.
martinr