【问题标题】:UIActivityIndicatorView always crashesUIActivityIndi​​catorView 总是崩溃
【发布时间】:2011-06-07 16:25:34
【问题描述】:

我的 UIActivityIndi​​catorView 总是让我的应用崩溃。
当我按下下载按钮时,指示器会显示并开始旋转。
但是当我停止它时,我只需要在某个地方触摸屏幕,我的应用就会崩溃。

.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 spinEnd];
    ...
}

【问题讨论】:

  • 请注意,在您的 initSpinner 方法中,您是直接访问 indicator ivar (indicator = ...),而不是通过属性修改器 (self.indicator = ...),因此指标不会被保留。
  • 在您编辑的代码版本中,您现在过度保留和泄漏活动指示器,因为您使用了属性 (self.indicator = ...),但您不再自动释放它。

标签: iphone xcode uiactivityindicatorview


【解决方案1】:

取而代之或自动释放它,控制它并在完成后调用 self.indicated = nil 手动释放它并在 dealloc 中释放它。 这样,您确定它不会在没有警告的情况下消失...

【讨论】:

  • 谢谢,它不再崩溃了!但我的指标也不会停止动画......
  • 在您的 spinEnd 方法中也将其从视图中移除。
【解决方案2】:

在你的函数中:

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

我建议不要将指标设置为零。事实上,设置self.indicator = nil 将使指标被释放。如果这也触发了释放,那么当主循环执行时,UI 可能无法正确重绘自身。注意:这只是我因您的奇怪行为而做出的假设。它可能有效,也可能无效。

我还会确保在指标停止时将hidesWhenStopped 设置为YES。总而言之,我会重写:

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

并在您的-dealloc 中发布indicator

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

顺便也修复一下initSpinner中的内存泄露问题:

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

需要注意的是,当你执行initSpinner时,如果indicator已经存在,分配一个新的UIActivityIndicatorViewself.indicator会使之前的self.indicator被释放。

编辑:

如果上述方法都不起作用,您可以再尝试两件事:

  1. -spinEnd 中将指标hidden 属性设置为YES;

  2. 可能我错了,但我突然想到在调用[indicator stopAnimating];之前设置self.indicator.hidesWhenStopped = YES可能更有效

【讨论】:

  • 嗯,我的第一个版本是自动发布的,它每次都会让我的应用崩溃。
  • 抱歉,这个带有 self.indicator 的版本适用于自动释放。但是没有停止指标的问题仍然存在。
  • @madmax:请看我的编辑,我提出了另一个建议。希望能帮助到你。关于自动释放的事情:在您的第一个代码版本中,您是自动释放并直接分配给 ivar;现在您正在使用该属性,它为您保留对象。
  • 不,也没有帮助。我在 spinEnd -> self.indicator.hidesWhenStopped = YES; [指标停止动画];指标.hidden = TRUE; [指标 removeFromSuperview];隐藏一个视图怎么这么难?
  • 是的,我也不明白这一点...您是否检查过 spinEnd 实际被调用并且 self.indicator 不在那里?我不知道还能想到什么......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多