2

I currently am using the code I found on an online tutorial to have the iPhone user select an image from their camera roll. Setting the image to the UIImageView works fine, but then I try to call a function on the image (every time a slider is moved). It turns out that the operating system is not holding onto the image, so when I try to access it (or the caching variable I made), it doesn't work (because the address gets set to 0x0000000).

If UIImage conformed to NSCopying, this would be simple. But, it doesn't. So, how do I copy an image so the operating system doesn't delete it?

Possible Duplicates

EDIT: The slider, when changed, calls this function:

- (IBAction)samplingSliderChanged:(id)sender {
    NSLog(@"%@", self.imageStay);
    float sample = self.samplingSlider.value * 0.6 + 0.2;
    self.samplingRateText.text =  [NSString stringWithFormat:@"%.0f%%", sample*100];
    //self.imageView.image = [self.brain sampleImage:self.imageStay atRate:sample];
    self.imageView.image = [self.brain sampleImage:self.imageStay.copy atRate:sample];
    NSLog(@"self.imageStay: %@, self.imageStay.copy: %@", self.imageStay, self.imageStay.copy);
}

The first time the slider is moved, my self.imageStay (the cache variable) has an address of 0x0000.

My show-the-camera-roll function is below:

-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = info[UIImagePickerControllerMediaType];
    UIImage * image;
    
    [self dismissViewControllerAnimated:YES completion:nil];
    
    image = info[UIImagePickerControllerOriginalImage];
    image = [self imageWithImage:image scaledToSize:CGSizeMake(256, 256)];
    self.imageView.image = image;

    if (_newMedia)
        UIImageWriteToSavedPhotosAlbum(image,
                                       self,
                                       @selector(image:finishedSavingWithError:contextInfo:),
                                       nil);
    self.imageView.image = image;
    self.imageStay = image


}

In here, the cache variable has the same memory address as image, and my guess is that this later gets deleted.

Community
  • 1
  • 1
Scott
  • 2,568
  • 1
  • 27
  • 39

1 Answers1

2

You shouldn't be worrying about NSCopying, or making a copy of a UIImage, this isn't your problem. You are losing the reference to the image in your imageView. The OS is holding onto the image, if not it would disappear from your imageView. I expect you just aren't referring to it correctly. Perhaps you should show what you mean by a 'caching variable'...

In any case a reliable way to get to the image currently displayed in your imageView is to obtain it from the imageView's image property, as self.imageView.image.

update

If self.imageView.image might be subject to filtering, and you also need to keep a reference to the original image (eg in self.imageStay) you should declare the imageStay property as

@property (nonatomic, strong) UIImage* imageStay;

If you have done this correctly, and still have a nil reference in self.imageStay, step through your code in the debugger to see what is going on here:

   self.imageView.image = image;

    if (_newMedia)
        UIImageWriteToSavedPhotosAlbum(image,
                                   self,
                                   @selector(image:finishedSavingWithError:contextInfo:),
                                   nil);
    self.imageView.image = image;
    self.imageStay = image

self.imageStay and self.imageView.image should now both have a reference to the same object. By the way, you second assignment of self.imageView.image = image here is redundant.

Then in - (IBAction)samplingSliderChanged:(id)sender you should find those references persisting.

Your problem might be caused if you have declared your @property imageStay as a weak reference. It should be strong to ensure that it persists.

foundry
  • 31,615
  • 9
  • 90
  • 125
  • But, I can't get `self.imageView.image`, because that overwrites what I'm trying to save (by sampling it, and I what the whole image). And I have edited it to show my code. – Scott Jan 27 '13 at 00:12
  • Is it your intention that self.imageStay keeps a reference to the original image, before any sampling? And imageView.image is the post-sampling version? – foundry Jan 27 '13 at 00:25
  • That is exactly what I am doing. And you're method worked! Thank you so much! – Scott Jan 27 '13 at 14:42