views:

1884

answers:

4

Hi

I am working on a subclass of UIImageView and one of the things I require is when the object is initalised with the initWithImage: message a 'copy' is created.

I must be confusing something because I can't see what is not working here..

- (id)initWithImage:(UIImage *)image {
[image retain];
if (self = [super initWithImage:image]) {

 if (!maskImage) {
  maskImage = [UIImage imageWithCGImage:[image CGImage]];
  if (maskImage != nil) {
   NSLog(@"Made mask image");
  } else {
   NSLog(@"Failed");
  }
  //maskImage = [UIImage imageNamed:@"image.png"];
 }
}

[image release];
return self;
}

There are no errors when I build this and the maskimage does appear to be created (i do not get the failure message). However, if I uncomment the line allocating from a png it works.

What am I missing?

Thanks!

A: 

I think you should just be able to do this:

maskImage = [image copy];
Mr. Matt
I dont think this will work, i dont think UIImages conform to the NSCopy protocol?
J T
A: 

Try this. Should work.

- (id)initWithImage:(NSString *)image {
if (self = [super initWithImage:image]) {

        if (!maskImage) {
                img = [UIImage imageNamed:image];
                maskImage = CGImageRetain(img.CGImage);
                if (maskImage != nil) {
                        NSLog(@"Made mask image");
                } else {
                        NSLog(@"Failed");
                }
        }
}

return self;
}
  1. Changes
    • pass NSString instead of image
    • no need to retain/release image
    • need to define img, maskImage in .h
    • maskImage in .h should have retain property set in @property ( e.g. @property (nonatomic, retain))
Jordan
Just a nit-picky note, but you might want to consider naming the -(id) initWithImage: method to something along the lines of initWithImageNamed: The way it is written leads me to think that the method would take a UIImage as a parameter, not a NSString with the name of the image file.
Brad Smith
Yep, on the fly copy/paste code from his example, but would make sense.
Jordan
A: 

First, you should set maskImage to nil, to make sure it isn't garbage:

self.maskImage=nil;

That may screwing up your line (if not now, then later):

if(!imaskImage)

Then, to make a copy, just implement NSCopying in a UIImage subclass. It's easy to do. Then you can type:

maskImage = [image copy];

Alternatively, you can convert the image to data, archive, then unarchive, then convert back to a UIImage. This gives you a complete copy of the image. It's a little more complex, but its the same method used for making deep copies of an object graph.

Corey Floyd
+1  A: 

You should retain created image, in example like this:

- (id)initWithImage:(UIImage *)image {
    if (self = [super initWithImage:image]) {
        if (!maskImage) {
                maskImage = [[UIImage imageWithCGImage:[image CGImage]] retain];
                if (maskImage != nil) {                
                        NSLog(@"Made mask image");
                } else {
                        NSLog(@"Failed");
                }
        }
    }
    return self;
}
Valerii Hiora