#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
приведет к освобождению предыдущего.
Редактировать:
Если ни одно из вышеперечисленных действий не сработало, вы могли бы попробовать еще две вещи:
-
установка
hidden
свойству indicator значения YES в-spinEnd
; -
возможно, я ошибался, но мне приходит в голову, что настройка
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 там не равен нулю? Я не знаю, о чем еще думать…