Как правильно сделать недействительным NSTimer - PullRequest
2 голосов
/ 02 июля 2010

У меня есть приложение для iPhone с NSTimer, называемое pressTimer, которое отключается каждый раз, когда кто-то касается этой кнопки.Проблема в том, что они много касаются кнопки, и я хочу, чтобы таймер остановился, когда они подняли палец.Итак, я объявил pressTimer в своем .h и синтезировал его в .m, затем назначил и запустил его в действии TouchDown, которое я создал.Я использую код [pressTimer invalidate] в своем действии TouchUpInside, которое должно отменить таймер, так как это глобальная переменная.Кажется, что таймер отменяет все нормально, но затем, когда я на самом деле отключаю таймер, программа полностью зависает, хотя я не получаю ошибок кода или предупреждений.Я нуб, поэтому, пожалуйста, не будьте слишком грубыми: 0

Обновление: журналы консоли - Спасибо, ребята!

continue
2010-07-01 16:39:30.981 Clickkr[1573:307] -[__NSCFData invalidate]: unrecognized selector sent to instance 0x154b40
2010-07-01 16:39:30.999 Clickkr[1573:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData invalidate]: unrecognized selector sent to instance 0x154b40'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x309a5fd3 __exceptionPreprocess + 114
    1   libobjc.A.dylib                     0x318b58a5 objc_exception_throw + 24
    2   CoreFoundation                      0x309a9a77 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
    3   CoreFoundation                      0x309a8f15 ___forwarding___ + 508
    4   CoreFoundation                      0x3093b680 _CF_forwarding_prep_0 + 48
    5   Clickkr                             0x00002b23 -[MyViewController addOne:] + 42
    6   CoreFoundation                      0x309307ad -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
    7   UIKit                               0x31e1f829 -[UIApplication sendAction:to:from:forEvent:] + 84
    8   UIKit                               0x31e1f7c9 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
    9   UIKit                               0x31e1f79b -[UIControl sendAction:to:forEvent:] + 38
    10  UIKit                               0x31e1f4ed -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
    11  UIKit                               0x31e1fb3b -[UIControl touchesEnded:withEvent:] + 342
    12  UIKit                               0x31e1e4ed -[UIWindow _sendTouchesForEvent:] + 368
    13  UIKit                               0x31e1de67 -[UIWindow sendEvent:] + 262
    14  UIKit                               0x31e19b5b -[UIApplication sendEvent:] + 298
    15  UIKit                               0x31e19507 _UIApplicationHandleEvent + 5022
    16  GraphicsServices                    0x30a8c147 PurpleEventCallback + 666
    17  CoreFoundation                      0x3097baab __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
    18  CoreFoundation                      0x3097d84f __CFRunLoopDoSource1 + 166
    19  CoreFoundation                      0x3097e62d __CFRunLoopRun + 520
    20  CoreFoundation                      0x309278eb CFRunLoopRunSpecific + 230
    21  CoreFoundation                      0x309277f3 CFRunLoopRunInMode + 58
    22  GraphicsServices                    0x30a8b6ef GSEventRunModal + 114
    23  GraphicsServices                    0x30a8b79b GSEventRun + 62
    24  UIKit                               0x31dc32a7 -[UIApplication _run] + 402
    25  UIKit                               0x31dc1e17 UIApplicationMain + 670
    26  Clickkr                             0x00002333 main + 70
    27  Clickkr                             0x000022e8 start + 40
)
terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.

Ответы [ 5 ]

7 голосов
/ 02 июля 2010

Вот как я делаю недействительными таймеры:

[timer invalidate];
timer = nil;

Проблема, с которой вы, вероятно, сталкиваетесь, заключается в том, что, как только ваш таймер становится недействительным, он удаляется из цикла выполнения, и когда кто-то хочет получить к нему доступ,ваша программа падает.После признания его недействительным, просто сделайте так, чтобы оно равнялось нулю.Таким образом, если кто-то захочет отправить сообщение или что-то с ним сделать, он отправит его на ноль.

1 голос
/ 22 сентября 2011
@interface
  NSTimer * yourTimer;

@property (nonatomic, retain) yourTimer;
@synthesize yourTimer;

@implement    
  self.yourTimer = [NSTimer scheduledTimerWithTimeInterval:5
                                                    target:self
                                                  selector:@selector(yourSelector)
                                                  userInfo:nil
                                                   repeats:NO];

  //Wherever you want to stop the timer,
  [yourTimer invalidate];
  self.yourTimer = nil;
0 голосов
/ 27 сентября 2014

Я бы лучше добавил проверку флага действительности и экземпляра объекта таймера

-(void) clearKeepAliveTimer {
    if(keepAliveTimer && [keepAliveTimer isValid]) {
        [keepAliveTimer invalidate];
        keepAliveTimer = nil;
    } }
0 голосов
/ 02 июля 2010

Ребята, я понял это после небольшого перебора. Метод Анауэля для остановки таймеров работал отлично, но по какой-то причине мое имя метода конфликтовало с селектором таймера, поэтому я изменил их оба. Я также добавил код Анауэля в метод, который использовал в качестве селектора. Спасибо!

0 голосов
/ 02 июля 2010

В журнале что-то не так с addOne ... как это связано с таймером?

...