views:

63

answers:

3

Hi, I have a strange problem with a UIView :

I want to show an Activity Indicator View that I created with Interface Builder to indicate long running activity.

In the viewDidLoad function of my principal viewController I init the ActivityIndicator View like this :

- (void)viewDidLoad {
    [super viewDidLoad];
    appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];        
    load = [[ActivityIndicatorViewController alloc] init];
    ...

When I push a button it call this IBAction :

- (IBAction)LaunchButtonPressed{            
    // Show the Activity indicator view.
    [self.view addSubview:load.view];

    // eavy work 
    [self StartWorking];    

    // Hide the loading view.
    [load.view removeFromSuperview];    
}

In the StartWorking function, I ask a request to an internet serveur and parse the XML file that it return me.

The problem is that if I Call my StartWorking function, the application do not start by showing the Activity Indicator view but with the StartWorking function. Whereas if I remove the call to StartWorking function, the view is shown.

Is someone able to explain me why? :s

+2  A: 

Have you tried to call the StartWorking method on a different thread?
Maybe its heavy process prevents other instructions to take place.

Look at the NSThread class, especially the detachNewThreadSelector:toTarget:withObject: method.

EDIT: About the pool problem, you need to create a pool in your StartWorking method, if it's called on a different thread:

- ( void )StartWorking
{
    NSAutoreleasePool * pool = [ [ NSAutoreleasePool alloc ] init ];

    /* Code here... */

    [ pool release ];
}
Macmade
It work fine, but all my autorelease object are leaking because there is no pool in place. :s
Raphael Pinto
You should be careful doing stuff (heavy function) in threads. I usually prefer implement lightweight function in thread and let the heavy one in main thread.
F.Santoni
+1  A: 

Hi it's normal,

Replace : [self.view addSubview:load.view];

With : [self performSelector:@selector(addLoadingSubview) afterDelay:0.1f];

And create the method : -(void)addLoadingSubview{[self.view addSubview:load.view];}

F.Santoni
I'have tryed but the result is the same. I used : [self performSelector:@selector(ShowActivityIndicatorView) withObject:nil afterDelay:0.1f];
Raphael Pinto
A: 

Ok, I found a solution based on santoni answer :

- (IBAction)LaunchButtonPressed{            
    // Show the Activity indicator view.
    [self performSelector:@selector(ShowActivityIndicatorView) withObject:nil afterDelay:0];

    // eavy work 
    [self performSelector:@selector(StartWorking) withObject:nil afterDelay:2];  

    // Hide the loading view.
    [load.view removeFromSuperview];    
}

The Activity Indicator view is dislayed before the call to the eavy function.

Thank's for answering.

Raphael Pinto