【问题标题】:iPhone: invalidate NSTimer from app delegate crashes appiPhone:使应用程序委托使应用程序崩溃的 NSTimer 无效
【发布时间】:2010-09-12 02:45:40
【问题描述】:

我正在尝试从我的应用程序委托中运行一个方法,该方法将一个对象保存在其他类中,并使计时器无效。我已经设置好了,当我的应用程序退出时,它会在我的类中运行该方法并保存并停止计时器。

在应用委托中:

- (void)applicationWillResignActive:(UIApplication *)application {

    // Save the mission because they are leaving the app
    if ([timeRun hasScore]) {
        [timeRun resetWithSave];
    }

}

它在“timeRun”类中调用的方法:

- (void)resetWithSave {
    // Save
    self.counterInt = 150;
    self.timer.text = [self timeInSeconds:counterInt];
    [start setBackgroundImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
    self.started = NO;
    self.score.text = @"0";
    [self saveMission];
    if ([countTimer isValid]) {
        [countTimer invalidate];
    }
    [table scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
}

但是,我遇到了崩溃:

2010-09-11 19:35:21.503 Score Card[2747:307] -[__NSCFType isValid]: unrecognized selector sent to instance 0x19e190
2010-09-11 19:35:21.594 Score Card[2747:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType isValid]: unrecognized selector sent to instance 0x19e190'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x30897ed3 __exceptionPreprocess + 114
    1   libobjc.A.dylib                     0x3002f811 objc_exception_throw + 24
    2   CoreFoundation                      0x30899683 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
    3   CoreFoundation                      0x308411d9 ___forwarding___ + 508
    4   CoreFoundation                      0x30840f90 _CF_forwarding_prep_0 + 48
    5   Score Card                          0x00006b3d -[TimeRun resetWithSave] + 272
    6   Score Card                          0x00002b39 -[Score_CardAppDelegate applicationWillResignActive:] + 80
    7   UIKit                               0x31ea6879 -[UIApplication _setActivated:] + 212
    8   UIKit                               0x31eda4ab -[UIApplication _handleApplicationSuspend:eventInfo:] + 238
    9   UIKit                               0x31eab301 -[UIApplication handleEvent:withNewEvent:] + 2200
    10  UIKit                               0x31eaa901 -[UIApplication sendEvent:] + 44
    11  UIKit                               0x31eaa337 _UIApplicationHandleEvent + 5110
    12  GraphicsServices                    0x31e4504b PurpleEventCallback + 666
    13  CoreFoundation                      0x3082cce3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
    14  CoreFoundation                      0x3082cca7 __CFRunLoopDoSource1 + 166
    15  CoreFoundation                      0x3081f56d __CFRunLoopRun + 520
    16  CoreFoundation                      0x3081f277 CFRunLoopRunSpecific + 230
    17  CoreFoundation                      0x3081f17f CFRunLoopRunInMode + 58
    18  GraphicsServices                    0x31e445f3 GSEventRunModal + 114
    19  GraphicsServices                    0x31e4469f GSEventRun + 62
    20  UIKit                               0x31e51123 -[UIApplication _run] + 402
    21  UIKit                               0x31e4f12f UIApplicationMain + 670
    22  Score Card                          0x000029ef main + 70
    23  Score Card                          0x000029a4 start + 40
)
terminate called after throwing an instance of 'NSException'
Program received signal:  “SIGABRT”.
kill
quit

为什么这会使我的应用崩溃?

【问题讨论】:

  • 告诉我们countTimer的定义

标签: iphone delegates crash nstimer uiapplicationdelegate


【解决方案1】:

凭直觉,你正在做类似的事情

countTimer = [NSTimer scheduledTimerWithTarget:...];

...

if ([countTimer isValid])
{
  [countTimer invalidate];
}

...


if ([countTimer isValid])
{
  [countTimer invalidate];
}

为您将“预定”计时器添加到运行循环中。然后它由运行循环保留。使其无效会将其从运行循环中删除,从而将其释放。如果没有其他东西保留它,它就会被释放。当您尝试再次使用它时,它会崩溃。

尝试类似[countTimer invalidate]; countTimer = nil;

或者,您可以保留计时器,但请注意,计时器会保留其目标,因此很容易以保留周期结束。

【讨论】:

  • 是的。由于您没有保留计时器(因为您通常不应该保留),所以您不知道它何时会被释放,除非它会在它的回调方法被调用之后。你应该在那个时候将它的引用设置为 nil,或者每当你使它无效时,因为它会在之后自动释放。
  • 你知道它什么时候被运行循环释放。你不知道它什么时候会被释放;那是不同的。
【解决方案2】:

看起来计时器从未初始化或被释放。有时,当它为 nil 时,随机对象也会抛出这样的异常。检查您的指针并保留计数!

【讨论】:

    猜你喜欢
    • 2011-06-25
    • 1970-01-01
    • 1970-01-01
    • 2011-02-13
    • 2017-04-25
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    相关资源
    最近更新 更多