Memory leak in MBProgressHUD - iphone

In below code there is about 3MB of leak.If I remove [self.view addSubview:progressDialog];
then their is no leak.
-(void)showProgressDialog:(NSString*)title setTimer:(BOOL)isTimerSet
{
progressDialog = [[MBProgressHUD alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
[progressDialog setLabelText:title];
progressDialog.dimBackground=YES;
[self.view addSubview:progressDialog];//Leak is here
[progressDialog show:YES];
}
-(void)hideProgressDialog
{
if(progressDialog !=nil)
{
[progressDialog hide:YES];
[progressDialog removeFromSuperview];
[progressDialog release];
progressDialog = nil;
}
}
Please help.

you are not releasing it progressDialog or if it is ivar, then use property instead of ivar, and synthesize it, then follow this approch
MBProgressHUD *obj = [[MBProgressHUD alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
self.progressDialog=obj;
[obj release];
like this
MBProgressHUD *obj = [[MBProgressHUD alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
self.progressDialog=obj;
[obj release];
[self.progressDialog setLabelText:title];
self.progressDialog.dimBackground=YES;
[self.view addSubview:self.progressDialog];//Leak is here
[self.progressDialog show:YES];

Related

display subviews with delay

When this action gets executed it displays secondviewcontroller directly what i want is that viewcontroller displays first and after 40 or 50 secs it displays secondviewcontroller next and so on.
- (void)displayviewsAction:(id)sender
{
PageOneViewController *viewController = [[PageOneViewController alloc] init];
viewController.view.frame = CGRectMake(0, 0, 320, 480);
SecondViewController *secondController = [[SecondViewController alloc] init];
secondController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:viewController.view];
[self.view addSubview:secondController.view];
[self.view bringSubviewToFront:viewController.view];
[self.view addSubview:toolbar];
[self.view sendSubviewToBack:viewController.view];
[self.view addSubview:toolbar];
}
Anyone have any ideas how i can do that.
Try making the view invisible and then quickly fading it in after 40 seconds have passed.
secondController.view.alpha = 0.0;
[self.view addSubview:secondController.view];
[UIView animateWithDuration:0.5
delay:40
options:UIViewAnimationCurveEaseInOut
animations:^{
secondController.view.alpha = 1.0;
}
completion:NULL
];
you can add the secondViewController in a separate method and call that method using performSelector:withObject:afterDelay
- (void)displayviewsAction:(id)sender {
PageOneViewController *viewController = [[PageOneViewController alloc] init];
viewController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:viewController.view];
[self performSelector:#selector(secondViewController) withObject:nil afterDelay:40];
}
-(void)secondViewController {
SecondViewController *secondController = [[SecondViewController alloc] init];
secondController.view.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:secondController.view];
}
An alternative/addition to the method detailed by Aravindhanarviless is to use an NSTimer:
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:40 target:self selector:#selector(showSecondViewController) userInfo:nil repeats:NO];

problem i loading progress indicator in iphone sdk?

I want to get list from server it is taking some time So at that time I'm displaying progress indicator. My problem sometimes the progress indicator is appearing and some times it is not appearing. The code I used is
-(void)viewWillAppear:(BOOL)animated
{
[self loadprogressIndicator];
}
-(void)loadprogressIndicator
{
MessengerAppDelegate* appDelegate = (MessengerAppDelegate*) [ [UIApplication sharedApplication] delegate];
[appDelegate showWaitingView];
[NSThread detachNewThreadSelector:#selector(statusIndicatorForRefresh) toTarget:self withObject:nil];
}
-(void)statusIndicatorForRefresh
{
NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self performSelectorOnMainThread:#selector(loadList) withObject:nil waitUntilDone:NO];
[NSThread exit];
[pool release];
}
-(void)loadList
{
MessengerAppDelegate* appDelegate = (MessengerAppDelegate*) [ [UIApplication sharedApplication] delegate];
customerList = [appDelegate getCustomersArray];
[theTableView reloadData];
[appDelegate removeWaitingView];
}
And in appdelegate.m I implemeted these two methods
- (void)showWaitingView
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGRect frame = CGRectMake(90, 190, 32, 32);
UIActivityIndicatorView* progressInd = [[UIActivityIndicatorView alloc] initWithFrame:frame];
[progressInd startAnimating];
progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
frame = CGRectMake(130, 193, 140, 30);
UILabel *waitingLable = [[UILabel alloc] initWithFrame:frame];
waitingLable.text = #"Processing...";
waitingLable.textColor = [UIColor whiteColor];
waitingLable.font = [UIFont systemFontOfSize:20];
waitingLable.backgroundColor = [UIColor clearColor];
frame = [[UIScreen mainScreen] applicationFrame];
UIView *theView = [[UIView alloc] initWithFrame:frame];
theView.backgroundColor = [UIColor blackColor];
theView.alpha = 0.7;
theView.tag = 999;
[theView addSubview:progressInd];
[theView addSubview:waitingLable];
[progressInd release];
[waitingLable release];
[window addSubview:[theView autorelease]];
[window bringSubviewToFront:theView];
[pool drain];
}
- (void)removeWaitingView
{
UIView *v = [window viewWithTag:999];
if(v) [v removeFromSuperview];
}
Can anyone please help me. Happy Coding..
Thanks in advance.
Praveena..
You are doing all your activity on the main thread. Your app will appear to be blocked because you block the UI thread.
Also what is the use of launching an NSThread if all it does is call a method on your main thread and not even wait for it to complete? You are doing no multithreading at all.
Your app does this:
in main thread:
show waiting view
do 1 run loop cycle
do your data processing
hide waiting view
since your data processing is in the main thread you block everything there. You should do the processing in a secondary thread and leave the main thread for UI handling.

iPhone: Progress Indicator

In my app when I download something from service, I show progress indicator:
- (void)setupProgressIndicator {
MBProgressHUD *progressHUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:progressHUD];
self.progressIndicator = progressHUD;
[progressHUD release];
}
[self.progressIndicator show:YES];
My view has Navigation Bar which I setup in my AppDelegate, and when indicator is shown, I still can tup on Navigation Bar Buttons...Can MBProgressHUB cover whole screen ??? Because I don't want to disable buttons on sync start and than make them enable on sync finish...I think indicator should cover whole screen. Any ideas ? Thanks...
Here is my implementation use it if you want
Put it in appDelegate and use from anywhere in the application.
#pragma mark -
#pragma mark Waiting View
- (void)showWaitingView {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGRect frame = CGRectMake(90, 190, 32, 32);
UIActivityIndicatorView* progressInd = [[UIActivityIndicatorView alloc] initWithFrame:frame];
[progressInd startAnimating];
progressInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
frame = CGRectMake(130, 193, 140, 30);
UILabel *waitingLable = [[UILabel alloc] initWithFrame:frame];
waitingLable.text = #"Processing...";
waitingLable.textColor = [UIColor whiteColor];
waitingLable.font = [UIFont systemFontOfSize:20];;
waitingLable.backgroundColor = [UIColor clearColor];
frame = [[UIScreen mainScreen] applicationFrame];
UIView *theView = [[UIView alloc] initWithFrame:frame];
theView.backgroundColor = [UIColor blackColor];
theView.alpha = 0.7;
theView.tag = 999;
[theView addSubview:progressInd];
[theView addSubview:waitingLable];
[progressInd release];
[waitingLable release];
[window addSubview:[theView autorelease]];
[window bringSubviewToFront:theView];
[pool drain];
}
- (void)removeWaitingView {
UIView *v = [window viewWithTag:999];
if(v) [v removeFromSuperview];
}
usual thing is to add an transparent view cover the entire screen and that will capture touch event. or you can make your HUD the size of the screen, with visible widget only in the center.
- (IBAction)showWithCustomView:(id)sender {
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"37x-Checkmark.png"]] autorelease];
HUD.customView.frame=CGRectMake(0, 0, 320, 460);//Ur answer
HUD.mode = MBProgressHUDModeCustomView;
HUD.delegate = self;
HUD.labelText = #"Completed";
[HUD show:YES];
[HUD hide:YES afterDelay:3];
}

The latest iPhone 4 has image display issue

The older 3GS, or iPod 4 are able to show the final tempimage, but on the iPhone 4, I don't see the tempview showing up on screen.
I stepped through it, getting imageData, tempimage allocated, tempview allocated, but the final tempview is not showing up.
-(void) display:(NSData*) imageData
{
tempimage= [[[UIImage alloc] initWithData:imageData] autorelease];
tempview=[[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)] autorelease];
if (tempimage) {
[tempview setImage:tempimage];
[self.view addSubview:tempview];
}
try like this..
-(void) display:(NSData*) imageData
{
if(imageData != nil)
{
tempimage= [[UIImage alloc] initWithData:imageData];
}
else
{
tempimage= [UIImage imageNamed:#"something.png"];
}
tempview=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
if (tempimage) {
[tempview setImage:tempimage];
[self.view addSubview:tempview];
}
if(imageData != nil)
{
[tempimage release];
}
[tempview release];
}

iphone memory deallocation issue with scrollview with image inside

I'm having trouble deallocating a UISCrollView that contains images.
There's something wrong with my code, but I cannot understand where.
this is a snippet of my code. It basically create a loops adding a uiscrollview with an image and removing.
If you run the code with instruments, no memory will be freed.
I also add some check for the retainCount, with no luck at all..
here's the code
- (void)loadView {
[super loadView];
CGRect theRect = CGRectMake(0, 0, 320, 480);
UIView *view = [[UIView alloc] initWithFrame:theRect];
[view setBackgroundColor:[UIColor purpleColor] ];
self.view = view;
[view release];
UIView *pippo = [[UIView alloc] initWithFrame:theRect];
[pippo setBackgroundColor:[UIColor redColor]];
[self.view addSubview:pippo];
[pippo release];
[self performSelector:#selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}
-(void)scrollAdd:(id)o {
CGRect theRect = CGRectMake(0, 0, 320, 480);
int numero = 1;
scroll = [[UIScrollView alloc] initWithFrame:theRect];
[scroll setContentSize:CGSizeMake( 320*numero,1)];
[scroll setScrollEnabled:YES];
UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"koala1b" ofType:#"jpg"]];
int dd = [img retainCount];
UIImageView *v2 = [[UIImageView alloc] initWithFrame:theRect];
[v2 setImage:img];
[scroll addSubview:v2];
dd = [v2 retainCount];
[v2 release];
dd = [v2 retainCount];
dd = [img retainCount];
[self.view addSubview:scroll];
[img release];
dd = [img retainCount];
[self performSelector:#selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}
-(void)scrollRemove:(id)o {
int dd = [scroll retainCount];
UIImageView *theV = [[scroll subviews] objectAtIndex:0];
dd = [theV retainCount];
[scroll removeFromSuperview];
dd = [theV retainCount];
[theV release];
dd = [theV retainCount];
dd = [scroll retainCount];
scroll = nil;
[self performSelector:#selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}
The issue is that you are releasing img when you shouldn't (which is probably being masked by the view hierarchy never being released), and you aren't releasing scroll when you should.
-(void)scrollAdd:(id)o {
CGRect theRect = CGRectMake(0, 0, 320, 480);
int numero = 1;
scroll = [[UIScrollView alloc] initWithFrame:theRect];
[scroll setContentSize:CGSizeMake( 320*numero,1)];
[scroll setScrollEnabled:YES];
UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"koala1b" ofType:#"jpg"]];
int dd = [img retainCount];
UIImageView *v2 = [[UIImageView alloc] initWithFrame:theRect];
[v2 setImage:img];
[scroll addSubview:v2];
[v2 release];
[self.view addSubview:scroll];
[img release];
dd = [img retainCount];
[self performSelector:#selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}
This should be:
-(void)scrollAdd:(id)o {
CGRect theRect = CGRectMake(0, 0, 320, 480);
int numero = 1;
scroll = [[UIScrollView alloc] initWithFrame:theRect];
[scroll setContentSize:CGSizeMake( 320*numero,1)];
[scroll setScrollEnabled:YES];
UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"koala1b" ofType:#"jpg"]];
UIImageView *v2 = [[UIImageView alloc] initWithFrame:theRect];
[v2 setImage:img];
[scroll addSubview:v2];
[v2 release];
[self.view addSubview:scroll];
[self performSelector:#selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}
Of course if you do this you need to also make a slight change in your view removal path:
-(void)scrollRemove:(id)o {
[scroll removeFromSuperview];
[scroll release];
scroll = nil;
[self performSelector:#selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}
I've basically reached the same conclusions as #Louis, but also made some comments within the code as to what I removed and why.
- (void)loadView {
[super loadView];
CGRect theRect = CGRectMake(0, 0, 320, 480);
UIView *view = [[UIView alloc] initWithFrame:theRect];
[view setBackgroundColor:[UIColor purpleColor] ];
self.view = view;
[view release];
UIView *pippo = [[UIView alloc] initWithFrame:theRect];
[pippo setBackgroundColor:[UIColor redColor]];
[self.view addSubview:pippo];
[pippo release];
[self performSelector:#selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}
-(void)scrollAdd:(id)o {
CGRect theRect = CGRectMake(0, 0, 320, 480);
int numero = 1;
scroll = [[UIScrollView alloc] initWithFrame:theRect];
[scroll setContentSize:CGSizeMake( 320*numero,1)];
[scroll setScrollEnabled:YES];
// img is already autoreleased, you're releasing again down below
// --- UIImage *img = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:#"koala1b" ofType:#"jpg"]];
UIImageView *v2 = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"koala1b.jpg"]];
v2.frame = theRect;
//--- [v2 setImage:img];
[scroll addSubview:v2];
[v2 release];
[self.view addSubview:scroll];
// NO !; img is autoreleased from imageWithContentsOfFile
//--- [img release];
[self performSelector:#selector(scrollRemove:) withObject:nil afterDelay:2.0f];
}
-(void)scrollRemove:(id)o {
//--- UIImageView *theV = [[scroll subviews] objectAtIndex:0];
[scroll removeFromSuperview];
// you don't own theV because you didn't create it here, or send it a retain. So NO release
// it also appears that you think you're responsible for releasing or cleaning up
// a view's subviews. NO. Just call [scroll removeFromSuperview] and let scroll view
// clean it's own resources.
//--- [theV release];
[scroll release];
scroll = nil;
[self performSelector:#selector(scrollAdd:) withObject:nil afterDelay:2.0f];
}