这似乎只是在对我的一个视图控制器运行单元测试时发生的,并且它非常随机。有时测试会通过,但大部分时间都会在同一个地方崩溃。
以下是来自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];
}];
}