开发者

UIActivityIndicatorView always crashes

开发者 https://www.devze.com 2023-03-10 15:43 出处:网络
My UIActivityIndicatorView always crashes my app. When I press my download button, the indicator shows and starts spinning.

My UIActivityIndicatorView always crashes my app.

When I press my download button, the indicator shows and starts spinning.

But when I stop it, I just have to touch the screen somewhere and my app crashes.

.h

@interface DownloadViewController : UIViewController < FinishedParsing, NSFetchedResultsControllerDelegate > 
{
    UIActivityIndicatorView* indicator;
}
@property (nonatomic, retain) UIActivityIndicatorView* indicator;

- (void)initSpinner;
- (void)spinBegin;
- (void)spinEnd;

.m

@implementation DownloadViewController

@synthesize indicator;

- (IBAction)download:(id)sender 
{
    [self initSpinner];
    [self spinBegin];

    [OJSGatewayCommunicationService parseArticles :self];
}

- (void)initSpinner 
{
    self.indicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]autorelease];    

    // we put our spinning "thing" right in the center of the current view
    CGPoint newCenter = (CGPoint) [self.view center];
    indicator.center = newCenter;   
    [self.view addSubview:indicator];   
}

- (void)spinBegin 
{
    [indicator startAnimating];
}

- (void)spinEnd 
{
    self.indicator.hidesWhenStopped = YES;
[indicator stopAnimating];
    indicator.hidden = TRUE;
    [indicator removeFromSuperview];
}

- (void) fetchPDF:(NSMutableArray *)chapters
{
    [self sp开发者_JAVA百科inEnd];
    ...
}


Instead or autoreleasing it, take control of it and release it manually by calling self.indicated = nil after you're done with it and release it in dealloc. That way, you're sure it won't vanish without warnings...


In your function:

- (void)spinEnd {
    [indicator stopAnimating];
    self.indicator = nil;
}

I would suggest not setting the indicator to nil. Indeed, setting self.indicator = nil will make the indicator be released. If this also triggers deallocation, it is possible that the UI will not be in a condition to redraw itself correctly when the main loop is executed. Notice: this is just an hypothesis I am making due to the strange behavior you are having. It may work or it may not.

I would also make sure that hidesWhenStopped is set to YES when the indicator is stopped. All in all, I would rewrite:

- (void)spinEnd {
    self.indicator.hidesWhenStopped = YES; //-- additional guarantee, but it should already be set
    [indicator stopAnimating];
}

and release indicator in your -dealloc:

- (void)dealloc {
    ....
    [_indicator release];
    _indicator = nil;
    ...
    [super dealloc];
}

By the way, also fix the memory leak you have in initSpinner:

- (void)initSpinner {
    self.indicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] autorelease];    
    ....

It is to be noted that, when you execute initSpinner, if an indicator was already there, assigning a new UIActivityIndicatorView to self.indicator will make the previous one to be released.

EDIT:

If none of the above haw worked, you could try two more things:

  1. setting the indicator hidden property to YES in -spinEnd;

  2. possibly I was wrong, but it occurs to me that setting self.indicator.hidesWhenStopped = YES could be more effective before calling [indicator stopAnimating];

0

精彩评论

暂无评论...
验证码 换一张
取 消