UIActivityIndicatorView always crashes
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:
setting the indicator
hidden
property to YES in-spinEnd
;possibly I was wrong, but it occurs to me that setting
self.indicator.hidesWhenStopped = YES
could be more effective before calling[indicator stopAnimating];
精彩评论