Memory issue with perform selector - iPhone - iphone

i got a problem and i don't know how to solve it. this is what i try to do: the user picks an image from his album on his iphone. while the image will be saved in the application folder, a actionsheet should popup with an activity indicator on it till the saving process is done. below you can see how i tried to do it, but i think there my code causes a memory problem (EXC_BAD_ACCESS), but i can't fix it.
when i debug, i found out, that both methods which are listed below will be called in a loop, that's what confuses me the most.
thanks in advance for your help.
sean
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage* img = [info objectForKey:UIImagePickerControllerOriginalImage];
img = [self rotateImage:img byOrientationFlag:img.imageOrientation];
NSMutableArray *args = [[NSMutableArray alloc] init];
activityLoadImage = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(-17.5, -11, 35, 35)];
activityLoadImage.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
activityLoadImage.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
actionSheetLoadImage = [[UIActionSheet alloc] initWithTitle:#""
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
actionSheetLoadImage.actionSheetStyle = UIBarStyleBlackOpaque;
[actionSheetLoadImage setMessage:NSLocalizedString(#"_LoadImage", #"loading image")];
[actionSheetLoadImage addSubview:activityLoadImage];
[actionSheetLoadImage showInView:self.view];
[actionSheetLoadImage setBounds:CGRectMake(0,-105,320,720)];
[args insertObject:picker atIndex:0];
[args insertObject:img atIndex:1];
[args insertObject:[info objectForKey:UIImagePickerControllerOriginalImage] atIndex:2];
[activityLoadImage performSelectorOnMainThread:#selector(startAnimating) withObject:nil waitUntilDone:NO];
[self performSelector:#selector(saveImage:) withObject:args afterDelay:0.1];
[args release];
}
- (void)saveImage:(NSMutableArray *)arguments
{
UIImagePickerController *picker = [[arguments objectAtIndex:0] retain];
UIImage *img = [[arguments objectAtIndex:1] retain];
UIImage *orgImg = [[arguments objectAtIndex:2] retain];
// writes the image to specific location with the given file name
NSData *imageData = [self getImageData:img];
[imageData writeToFile:[self getImagePath] atomically:YES];
// writes the small image to specific location with the given file name
imageData = [self getSmallImageData:img];
[imageData writeToFile:[self getSmallImagePath] atomically:YES];
// sets UIImage for the UIImageView
[self setViewInfo];
lblNoImage.hidden = TRUE;
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
[self.tableView reloadData];
[activityLoadImage performSelectorOnMainThread:#selector(stopAnimating) withObject:nil wait UntilDone:NO];
[actionSheetLoadImage dismissWithClickedButtonIndex:0 animated:YES];
[activityLoadImage release];
[actionSheetLoadImage release];
}

You're passing args into saveImage and then releasing it. Since the method is waiting 0.1 seconds before executing by this time args has already been released. Try not releasing args to see if that fixes your problem then think about a better way to manage the memory, possibly retain it as a property of the class.

Related

Memory warning when tranfer image picked camera to one view to other

I open the camera on button click and take the image in uiimage and then transfer that uiimage to other view
But i receive memory warning when i do this 4-5 time.
Below is the code i worked for:-
-(void)imagePickerController:(UIImagePickerController*)picker_camera didFinishPickingMediaWithInfo:(NSDictionary*)info
{
[picker_camera dismissModalViewControllerAnimated:YES];
UIImage *image=[[UIImage alloc] init];
image=[info objectForKey:#"UIImagePickerControllerOriginalImage"];
[self Methodcall:image];
//Image_camera=image;
// NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];
//printf("first\n");
// [self performSelector:#selector(Methodcall) withObject:nil afterDelay:1];
//printf("ok\n");
//[apool release];
}
-(void)Methodcall:(UIImage *)image{
ImageDisplayViewController *ImageDisplayViewController_obj=[[ImageDisplayViewController alloc] initWithNibName:#"ImageDisplayViewController" bundle:nil];
ImageDisplayViewController_obj.image_FRomCamera=image;
NSLog(#"image===>%# camera==>%#",image,ImageDisplayViewController_obj.image_FRomCamera);
[self.navigationController pushViewController:ImageDisplayViewController_obj animated:YES];
// [ImageDisplayViewController_obj release];
}
-(IBAction)TakePhotoCamera:(id)sender{
#try
{
UIImagePickerController *picker_camera = [[UIImagePickerController alloc] init];
picker_camera.sourceType = UIImagePickerControllerSourceTypeCamera;
picker_camera.delegate = self;
[self presentModalViewController:picker_camera animated:YES];
[picker_camera release];
}
#catch (NSException *exception)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Camera" message:#"Camera is not available " delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
Does any one help me out please.
Thanks in advance.
I assume you're not using ARC (is there any particular reason for this?)
Firstly, you are allocating an UIImage instance that's never used:
UIImage *image=[[UIImage alloc] init];
image=[info objectForKey:#"UIImagePickerControllerOriginalImage"];
should be changed to:
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
Next, you are not releasing ImageDisplayViewController_obj instance here:
// [ImageDisplayViewController_obj release];
Uncomment this line.
Golden rule of memory management: Always release objects you don't need any more and don't retain anything you don't need.
I would highly recommend using ARC if you're new to Obj-C and/or memory management.
Some other suggestions:
How to check existence of camera?
Avoid exceptions
Follow coding conventions - don't name your variables picker_camera (use pickerCamera), or ImageDisplayViewController_obj (use imageController or imageVC).

Fgallery save image to iPhone

Hi Sorry for being a noob but I'm learning. I have Fgallery working in my app but now I want to connect a bar button to an action to save the image to the phone. I need some code that gives me the current image (in the large image view) I hope someone can help me out with this. This is what I have:
- (void)handleEditCaptionButtonTouch:(id)sender {
// here we could implement some code to change the caption for a stored image
[networkGallery saveImageAtIndex:[networkGallery currentIndex]];
}
And here I have an image hard-coded but I need the current image:
- (void)saveImageAtIndex:(NSUInteger)index
{
UIImage *image = [UIImage imageNamed:#"background.png"];
if(image != nil){
UIImageWriteToSavedPhotosAlbum(image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
return;
}
//saveImage method
-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
[BT_debugger showIt:self:[NSString stringWithFormat:#"finished saving image: %#", #""]];
NSString *message;
NSString *title;
if (!error) {
title = NSLocalizedString(#"SaveSuccessTitle", #"");
message = NSLocalizedString(#"SaveSuccessMessage", #"");
} else {
title = NSLocalizedString(#"SaveFailedTitle", #"");
message = [error description];
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:NSLocalizedString(#"ButtonOK", #"")
otherButtonTitles:nil];
[alert show];
[alert release];
}
Any help would be very appreciated.
Thanks in advance
DK
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
img.image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
[self dismissModalViewControllerAnimated:YES];
}
If someone else is looking for an answer. Here it is:
FGalleryPhoto *photo = [_photoLoaders objectForKey:[NSString stringWithFormat:#"%i", index]];
UIImage *saveImage = [photo fullsize];
In code above, in the stringWithFormat method, replace index with _currentIndex
FGalleryPhoto *photo = [_photoLoaders objectForKey:[NSString stringWithFormat:#"%i", _currentIndex]];
UIImage *saveImage = [photo fullsize];

Emailing photo taken with ImagePickerController?

In my app I want to:
a.) Present camera to user to take picture
b.) Create email and attach picture taken
I figured out how to take the picture. But, I don't know how to attach it to the email. In the examples I've seen the filename is known. This is one example.
picker.mailComposeDelegate = self;
[picker setSubject:#"I have a pencil for you"];
UIImage *roboPic = [UIImage imageNamed:#"RobotWithPencil.jpg"];
NSData *imageData = UIImageJPEGRepresentation(roboPic, 1);
[picker addAttachmentData:imageData mimeType:#"image/jpg" fileName:#"RobotWithPencil.jpg"];
NSString *emailBody = #"This is a cool image of a robot I found. Check it out!";
[picker setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:picker animated:YES];
I am getting the image from the callback method and it does get stored in the camera roll.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[picker dismissModalViewControllerAnimated:TRUE];
[picker release];
}
But from there, I'm not sure how to attach the image to the email? Mainly because I don't know what the filename is when a photo is added to the camera roll when the UIImagePickerController camera source is used to obtain it?
So, I guess I need to either:
a.) Find a way to get the name of the image file once it is saved OR
b.) Another way to attach UIImage data as an email attachment.
Any help appreciated.
maybe I don't understand what you are trying to do UI wise, but why would this not work from your code provide:
EDIT: (changed code to use a delegate)
- (void)imagePickerController:(UIImagePickerController *)imagepicker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// Access the uncropped image from info dictionary
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
if([delegate respondsToSelector:#selector(didSelectImage:)])
[delegate didSelectImage:image];
}
this goes in your header file (usually above your class declaration):
#protocol PostHelperDelegate <NSObject>
#optional
- (void)DimissModal;
//image data for image selected
- (void)DidSelectImage:(UIImage*)image;
#end
also you need to create this property in your class
#property(nonatomic,assign)id<PostHelperDelegate>* delegate; //don't forgot to synthizie
then in the class implementing the delegate you will assign the delegate your class:
Poster = [[delegateclass alloc] init];
Poster.delegate = self;
then just add the delegate function:
- (void)DidSelectImage:(UIImage*)image
{
//handle image here
}
I simplify this quite a bit, let me know if you have any trouble getting it working
http://www.roostersoftstudios.com/2011/04/12/simple-delegate-tutorial-for-ios-development/
BEFORE UPDATE:
personally I would use a delegate to notify that the image has been picked and than launch the mail picker, but that is another thing. As far as the UIImage, I don't know a way or have never found a way to name/or get a name from the UIImagePicker as I do not believe they are named anything meaningful. Any questions on the delegate or further explanation let me know.
use bellow code
-(void)yourmethodname_clicked{
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
}
else{
UIAlertView *altnot=[[UIAlertView alloc]initWithTitle:#"Camera Not Available" message:#"Camera Not Available" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[altnot show];
[altnot release];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissModalViewControllerAnimated:YES];
MFMailComposeViewController *mailpicker = [[MFMailComposeViewController alloc] init];
[mailpicker.navigationBar setTintColor:[UIColor blackColor]];
mailpicker.mailComposeDelegate = self;
[mailpicker setSubject:#"set your subject"];
NSArray *toRecipients = [NSArray arrayWithObjects: nil];
[mailpicker setToRecipients:toRecipients];
UIImage *picture = [info objectForKey:#"UIImagePickerControllerOriginalImage"]];;
NSData *imageData = UIImagePNGRepresentation(picture);
[mailpicker addAttachmentData:imageData mimeType:#"image/png" fileName:#"set your file name"];
NSString *emailBody = #"set your body string";
[mailpicker setMessageBody:emailBody isHTML:YES];
[mailpicker setSubject:#"set your subject"];
mailpicker.title = #"Email";
[self presentModalViewController:mailpicker animated:YES];
[mailpicker release];
}
may this help you

Error in Load image in NSThread?

I have a url which contain image address, i want to load that image via NSThread but i am facing problem. I am doing thing like this.
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 10, 55, 57)];
[NSThread detachNewThreadSelector:#selector(showImage) toTarget:self withObject:nil];
[self.view addSubview:imageView];
- (void) showImage {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *url = [NSURL URLWithString:temp.strUrl];
UIImage *chart = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
[url release];
imageView.image = chart;
[pool release];
}
Please help me on that.
the problem is here.
[url release];
you are not supposed to release the url object . as you haven't alocated it, may be that is what you are facing problem with.

UIImageView setImage Leaks?

Have been searching for a solution to this problem for endless hours now. The problem is really simple. I have a UIImageView in the nib, i'm loading a image from internet and sets the UIIImageView with the image. I'm releasing the viewController. Dealloc is actually getting called(!) and loads the viewController and the image again. This can be done by entering background mode really easy. The Instrument Leaks doesn't report any leaks, BUT it shows in allocation that it keeps the image in the memory and it keeps growing.
Basic example:
-(id)init {
if((self = [super init])) {
id path = [NSString stringWithFormat:#"http://www.aSite.com/largeImage.jpg"];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
UIImage* img = [[UIImage alloc] initWithData:urlData];
[background setImage:img];
[urlData release];
[img release];
}
return self;
}
-(void)dealloc {
[background release];
[super dealloc];
}
Some people say that UIImageView actually leaks, or actually CGImage. Some people say that Instrument aren't showing correctly. I'm getting Memory Warning after 10-15 times of doing this with a 2.5mb large image. Results are from real device and latest iOS (or atleast 4-5 weeks ago). As UIImageView is used by so many people i thought it would be easy to find the problem or get a fix from apple?
Source of CGImage Leak:
(iphone) UIImageView setImage: leaks?
EDIT: I was abit tierd when i wrote the example. Example is correct now. I have also tried with autoreleased object and same "leak" is still there. Please answer the question if you gonna write an answer.
release the url after setting the image
[background setImage:[UIImage imageWithData:urlData]];
[urlData release];
[img release];
In the following code you are making some mistakes.
[urlData release];
[background setImage:[UIImage imageWithData:urlData]];
you should use
if((self = [super init])) {
id path = [NSString stringWithFormat:#"http://www.aSite.com/largeImage.jpg"];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
UIImage* img = [[UIImage alloc] initWithData:urlData];
[background setImage:img];
[urlData release];
[img release];
}
Can't you replace
[background setImage:[UIImage imageWithData:urlData]];
with
[background setImage:img];
UPDATE
I think this should also help
if((self = [super init])) {
id path = [NSString stringWithFormat:#"http://www.aSite.com/largeImage.jpg"];
NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
[background setImage:[UIImage imageWithData:urlData]];
[urlData release];
}
Have you tried:
-(id)init {
if((self = [super init]))
{
[background setImage:
[UIImage imageWithData:
[NSData dataWithUrl:
[NSUrl urlWithString:
#"http://www.aSite.com/largeImage.jpg" ]]]
];
}
return self;
}
-(void)dealloc {
[super dealloc];
}
clean and with no memory leaks!