NSTimer, который не делает недействительным (или странная проблема с памятью, которую я не могу решить) - PullRequest
0 голосов
/ 10 сентября 2011

У меня огромная проблема с объектом NSTimer.Я не могу объяснить это поведение, и я постараюсь объяснить как можно лучше.

У меня есть функция, которая называется placeAdvertise.В этой функции есть несколько операций со статическими методами, которые используют в качестве параметра один из моих объектов (другое представление):

if (self.adsController == nil) {
    self.adsController = [[AdsController alloc] ...];
    [self.view addSubView: self.adsController.view;
}

if (banner != nil) {

    self.adsController.banner = banner;
    [self.adsController updateBanner];

    //If a previous timer is still working (because this method can be called multiple times) invalidate
    if (self.adsTimer != nil)
        [self.adsTimer invalidate];

    [Advertisement operation1: self.adsController];
    [Advertisement operation2: self.adsController];

    self.adsTimer = [NSTimer scheduledTimerWithTimeInterval: 5 ...];

}

Последний таймер вызывает другую функцию, называемую quitAdvertise, но он никогда не вызывается (когданеудача производится).Кажется, что код работает нормально в нормальных условиях, контроллер рекламы работает правильно, баннер размещается, и таймер вызывает adsTimer, который закрывает баннер.

Проблема появляется, если всплывающее представление (возврат назад) итолкни еще раз.Как только представление загружено, я нажимаю кнопку, которая запускает код, размещенный ранее.Код выполняется хорошо, , но в «середине» выполнения , в [Объявление операции 1: self.adsController] появляется EXC_BAD_ACCESS:

[MyController AdvertisingController]: сообщение отправлено в освобожденный экземпляр 0x4e9b420

Это как в середине кода, мой объект освобождается .У меня нет никакого кода, который вызывает освобождение объекта, только dealloc, который не был вызван для этого экземпляра представления (был вызван для предыдущего представления, которое всплыло).

Как это может быть возможно?Есть ли способ отладить это в лучших условиях?

Я использовал NSZombieEnabled.

Спасибо!

*** Небольшая правка для комментариев ***

1) AdsController выделяется следующим образом:

self.adsController = [[AdsController alloc] initWithNibName:nil bundle:nil];

После в методе dealloc:

[self.adsController release];

[super dealloc];

2) Уважение к таймеру:

It is allocated with repeat NO. After in dealloc:

if (self.adsTimer != nil) [self.adsTimer invalidate];

Это правильно?

Ответы [ 3 ]

1 голос
/ 11 сентября 2012

[NSTimer scheduledTimerWithTimeInterval] добавит таймер к текущему циклу выполнения. Если текущий поток является фоновым потоком, возможно, что поток завершился и таймер никогда не будет запущен Попробуйте добавить таймер в основной цикл выполнения.

1 голос
/ 10 сентября 2011

Исходя из опубликованного кода, выглядит так, как будто вы «выталкиваете» это представление, но все еще может быть действительный NSTimer, который сохранит свою цель. Вы можете попытаться сделать NSTimer [[self adsTimer] invalidate] недействительным в вашем методе viewWillDisappear: (при условии, что у вас есть viewController - и , если у вас его нет, я бы порекомендовал использовать его).

Сложно провести диагностику по предоставленному вами коду - хотя краткость и велика, в этом случае может пригодиться немного больше.

0 голосов
/ 17 сентября 2011

Просто чтобы уточнить, в чем была проблема.

Был один NSNotification, который был нажат beign, только если таймер был активен.Это заставило меня поверить в то, что проблема была в таймере, но биг-бэнд был зафиксирован в выпущенной форме.

Итак, очень важно очень осторожно удалять наблюдателя из любого уведомления, когда формавыскочил.

Я просто хочу поблагодарить вас за помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...