UIActivityIndi​​catorView 总是崩溃

发布于 2024-11-14 16:47:54 字数 1352 浏览 2 评论 0原文

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

.h.m

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青芜 2024-11-21 16:47:55

在您的函数中:

- (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已经存在,则分配一个新的UIActivityIndi​​catorViewself.indicator 将使前一个被释放。

编辑:

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

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

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

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];

一张白纸 2024-11-21 16:47:54

相反,或者自动释放它,控制它并在完成后调用 self.indicated = nil 手动释放它并在 dealloc 中释放它。
这样,你就可以确定它不会在没有警告的情况下消失......

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文