在iOS模拟器上运行XCTest单元测试时发生CFRelease崩溃

时间:2015-11-16 09:56:27

标签: ios unit-testing memory-management xctest

这似乎只是在对我的一个视图控制器运行单元测试时发生的,并且它非常随机。有时测试会通过,但大部分时间都会在同一个地方崩溃。

以下是来自Xcode的堆栈跟踪:

#0  0x000000010e66727c in CFRelease ()
#1  0x000000011b4b1e00 in 0x11b4b1e00 ()
#2  0x000000010e667268 in CFRelease ()
#3  0x000000010de060b8 in (anonymous namespace)::AutoreleasePoolPage::pop(void*) ()
#4  0x000000011b325c23 in -[XCTestCase performTest:] ()
#5  0x000000011b3238d1 in -[XCTestSuite performTest:] ()
#6  0x000000011b3238d1 in -[XCTestSuite performTest:] ()
#7  0x000000011b3238d1 in -[XCTestSuite performTest:] ()
#8  0x000000011b310adc in __25-[XCTestDriver _runSuite]_block_invoke ()
#9  0x000000011b3312e3 in -[XCTestObservationCenter _observeTestExecutionForBlock:] ()
#10 0x000000011b310a28 in -[XCTestDriver _runSuite] ()
#11 0x000000011b311787 in -[XCTestDriver _checkForTestManager] ()
#12 0x000000011b359b23 in _XCTestMain ()
#13 0x000000010e6c2ffc in __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ ()
#14 0x000000010e6b8c85 in __CFRunLoopDoBlocks ()
#15 0x000000010e6b83e2 in __CFRunLoopRun ()
#16 0x000000010e6b7e08 in CFRunLoopRunSpecific ()
#17 0x0000000111687ad2 in GSEventRunModal ()
#18 0x000000010efad30d in UIApplicationMain ()
#19 0x000000010b76c134 in main at /Users/abc/Projects/xyz/Supporting Files/main.m:14
#20 0x000000011060292d in start ()
#21 0x000000011060292d in start ()

断点附近的汇编代码引用了一个字符串,似乎表明NULL参数已传递给CFRelease

    0x10e667252 <+1170>: callq  0x10e653af0               ; CFAllocatorDeallocate
    0x10e667257 <+1175>: cmpq   %rbx, %r13
    0x10e66725a <+1178>: je     0x10e667013               ; <+595>
    0x10e667260 <+1184>: movq   %rbx, %rdi
    0x10e667263 <+1187>: callq  0x10e666dc0               ; <+0>
    0x10e667268 <+1192>: jmp    0x10e667013               ; <+595>
    0x10e66726d <+1197>: leaq   0x329469(%rip), %rax      ; "*** CFRelease() called with NULL ***"
    0x10e667274 <+1204>: movq   %rax, 0x35994d(%rip)      ; gCRAnnotations + 8
    0x10e66727b <+1211>: int3   
->  0x10e66727c <+1212>: jmp    0x10e667282               ; <+1218>

有没有人知道为什么会发生这种情况?

我正在使用Xcode 7.1。

感谢。

修改

这大致是崩溃测试的样子:

self.navigationController = [[UINavigationController alloc] init];
self.viewControllerMocks = @{
    FixtureViewControllerKey: OCMClassMock([UIViewController class]),
    // ... more UIViewController mocks
};
self.menuViewController = [[MenuViewController alloc] initWithInnerNavigationController:self.navigationController initialViewControllerKey:FixtureViewControllerKey viewControllers:self.viewControllerMocks];
(void)self.menuViewController.view;

[self simulateTapOnMenuItemWithTitle:@"Some button"];
XCTAssertEqual(self.navigationController.viewControllers[0],
               self.viewControllerMocks[MenuViewControllerSomeKey]);

这是simulateTapOnMenuItemWithTitle:的定义方式:

- (void)simulateTapOnMenuItemWithTitle:(NSString *)title {
    UIButton *button = [self.menuViewController.view testsFindButtonWithTitle:title];
    [button testsSimulateTap];
}

// Helper methods defined in a UIView category

- (UIView *)testsFindSubviewUsingBlock:(BOOL (^)(UIView *subview))block {
    for (UIView *subview in self.subviews) {
        if (block(subview)) {
            return subview;
        }
        UIView *foundSubview = [subview testsFindSubviewUsingBlock:block];
        if (foundSubview != nil) {
            return foundSubview;
        }
    }
    return nil;
}

- (UIButton *)testsFindButtonWithTitle:(NSString *)title {
    return (UIButton *)[self testsFindSubviewUsingBlock:^BOOL(UIView *subview) {
        return [subview isKindOfClass:[UIButton class]] && [((UIButton *)subview).titleLabel.text isEqualToString:title];
    }];
}

0 个答案:

没有答案