【问题标题】:iOS Logic Unit Test target crashes after unit test passes with NSTimer使用 NSTimer 通过单元测试后,iOS 逻辑单元测试目标崩溃
【发布时间】:2011-12-31 02:27:13
【问题描述】:

我想要一个计时器类,它可以在还剩 1/2/3 秒时向委托人发送消息。

我的测试目标经常崩溃。

  • iOS 逻辑单元测试目标。
  • 使用重复的 NSTimer 测试持续时间的类
  • 一个没有断言的测试。测试通过,但随后目标崩溃:

/Developer/Tools/RunPlatformUnitTests.include: line 415: 770 Bus error "${THIN_TEST_RIG}" "${OTHER_TEST_FLAGS}" "${TEST_BUNDLE_PATH}"

在我看来,这是某种内存分配错误,但我无法弄清楚我错过了什么。该问题与停止计时器例程有关。只有当计时器用完时,目标才会崩溃。

我尝试过的事情

  • 构建和分析 - 未报告错误
  • 从链接器标志中移除 -framework 和 UIKit
  • 删除 dealloc - 这没有任何效果

测试代码

-(void)testGivenThreeSecondDurationAtOneSecondDelegateShouldBeToldToShowGreenCard {
    JGTimerController *timer = [JGTimerController timerWithDurationValue:1 delegate:nil];
    [timer startTimer];

    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.1]];
}

类代码

@interface JGTimerController : NSObject {
    NSNumber    *duration;
    NSTimer     *timer;
    id <NSObject, JGTimerControllerDelegate> _delegate;
}
@property (nonatomic, retain) NSNumber *duration;
... public methods...
@end


@implementation JGTimerController

@synthesize duration;

+(JGTimerController *)timerWithDurationValue:(NSUInteger)durationValue delegate:(id <JGTimerControllerDelegate>)delegate_ {
    JGTimerController *instance = [[[JGTimerController alloc] initWithDurationValue:durationValue delegate:delegate_] autorelease];
    return instance;
}

-(JGTimerController *)initWithDurationValue:(NSUInteger)durationValue delegate:(id <JGTimerControllerDelegate>)delegate_ {
    self = [super init];
    timer = nil;
    [self setDurationValue:durationValue];
    _delegate = delegate_;
    return self;
}

-(NSUInteger)durationValue {
    NSNumber *result = [self duration];
    return result ? [result intValue] : 0;
}

-(void)setDurationValue:(NSUInteger)value_ {
    [self setDuration:[NSNumber numberWithInt:value_]];
}

-(BOOL)stopTimerAtZeroDuration:(NSTimer *)timer_ {
    if ([self durationValue] == 0) {
        [self stopTimer];
        return YES;
    }
    return NO;
}

-(void)startTimer {
    if ([self stopTimerAtZeroDuration:nil])
        return;

    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerDidCountDownByASecond:) userInfo:nil repeats:YES];
}

-(void)stopTimer {
    if ([self durationValue] == 0 && [_delegate conformsToProtocol:@protocol(JGTimerControllerDelegate)])
        [_delegate showRedCard];

    [timer invalidate];
    [timer release];
}

-(BOOL)timerIsRunning {
    return (timer != nil);
}

-(void)timerDidCountDownByASecond:(NSTimer *)timer_ {
    [self setDurationValue:[self durationValue] - 1];
    [self stopTimerAtZeroDuration:timer_];
}

-(void)dealloc {
    [_delegate release];
    [timer release];
    [duration release];
    [super dealloc];
}

@end

【问题讨论】:

    标签: ios cocoa-touch unit-testing nstimer


    【解决方案1】:

    dealloc 中应该没有 [_delegate release],因为你没有保留它。

    【讨论】:

      【解决方案2】:

      同样,不应释放计时器。 NSTimer 和其他所有 NSObject 一样,如果你没有分配、复制或保留,则不需要释放。

      【讨论】:

      • 我非常确定我已经尝试删除 [timer release] 行,但它仍然崩溃。但是删除了这个,嘿!有效。非常感谢!
      猜你喜欢
      • 1970-01-01
      • 2017-08-15
      • 2018-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 2012-02-05
      相关资源
      最近更新 更多