UIActivityIndicatorView всегда выходит из строя

#iphone #xcode #uiactivityindicatorview

#iPhone #xcode #uiactivityindicatorview

Вопрос:

Мой UIActivityIndicatorView всегда приводит к сбою моего приложения.
Когда я нажимаю кнопку загрузки, индикатор загорается и начинает вращаться.
Но когда я останавливаю его, мне просто нужно где-то коснуться экрана, и мое приложение вылетает.

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

Комментарии:

1. Обратите внимание, что в вашем initSpinner методе вы обращаетесь к indicator ivar напрямую ( indicator = ... ), а не через свойство mutator ( self.indicator = ... ), поэтому индикатор не сохраняется.

2. В вашей отредактированной версии кода вы теперь чрезмерно сохраняете и пропускаете индикатор активности, потому что вы используете свойство ( self.indicator = ... ), но вы больше не запускаете его автоматически.

Ответ №1:

Вместо того, чтобы автоматически запускать его, возьмите его под контроль и освободите вручную, вызвав self.указано = nil после того, как вы закончите с ним, и освободите его в dealloc. Таким образом, вы уверены, что он не исчезнет без предупреждений…

Комментарии:

1. Спасибо, он больше не вылетает! Но мой индикатор также не прекращает анимацию…

2. Также удалите его из представления в вашем методе spinEnd.

Ответ №2:

В вашей функции:

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

Я бы посоветовал не устанавливать для индикатора значение nil. Действительно, настройка self.indicator = nil приведет к отключению индикатора. Если это также вызывает освобождение, возможно, что пользовательский интерфейс не будет в состоянии корректно перерисовать себя при выполнении основного цикла. Обратите внимание: это всего лишь гипотеза, которую я выдвигаю из-за вашего странного поведения. Это может сработать, а может и нет.

Я бы также убедился, что hidesWhenStopped установлено значение YES , когда индикатор остановлен. В общем, я бы переписал:

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

и отпустите indicator в вашем -dealloc :

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

Кстати, также устраните утечку памяти, которая у вас есть в initSpinner :

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

Следует отметить, что при выполнении, initSpinner если indicator an уже был там, назначение нового UIActivityIndicatorView для self.indicator приведет к освобождению предыдущего.

Редактировать:

Если ни одно из вышеперечисленных действий не сработало, вы могли бы попробовать еще две вещи:

  1. установка hidden свойству indicator значения YES в -spinEnd ;

  2. возможно, я ошибался, но мне приходит в голову, что настройка self.indicator.hidesWhenStopped = YES могла бы быть более эффективной перед вызовом [indicator stopAnimating];

Комментарии:

1. Ну, моя первая версия была с автозапуском, и это каждый раз приводило к сбою моего приложения.

2. Извините, эта версия с self.indicator работает с автозапуском. Но проблема с не останавливающимся индикатором все еще существует.

3. @madmax: пожалуйста, посмотрите мою правку, я выступил с другим предложением. Надеюсь, это поможет. Что касается автоматического выпуска: в вашей первой версии кода вы выполняли автоматический выпуск и присваивали его непосредственно ivar; теперь вы используете свойство, которое сохраняет объект для вас.

4. Нет, также никакой помощи. Я делаю это в spinEnd -> self.indicator.hidesWhenStopped = YES; [индикатор перестает работать]; indicator.hidden = TRUE; [индикатор удаляется из просмотра]; Как может быть так сложно просто скрыть представление?

5. да, я тоже этого не понимаю… вы проверили, что spinEnd действительно вызывается и self.indicator там не равен нулю? Я не знаю, о чем еще думать…