如果多个测试需要运行dispatch_once(),则只有一个测试通过。
以下是问题示例(非 ARC 代码):
#import <XCTest/XCTest.h>
@interface TestBrokenDispatchOnce : XCTestCase
@end
@implementation TestBrokenDispatchOnce
+(NSArray*) get {
static NSArray* _get;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_get=[NSArray arrayWithObjects:@(1),@(2),nil];
});
return _get;
}
- (void)testOne {
for(NSNumber* n in [[self class] get]) {
NSLog(@"%@",n);
}
XCTAssertTrue(YES, @"pass");
}
- (void)testTwo {
// will die here with access exception
for(NSNumber* n in [[self class] get]) {
NSLog(@"%@",n);
}
XCTAssertTrue(YES, @"pass");
}
@end
单独运行的每个测试用例都会通过,但如果同时运行,第二个测试用例将会失败。
我看到的实际问题是针对(非 ARC 库)进行测试,该库使用dispatch_once 延迟初始化数组,但失败与这个最小示例相同。我猜测 XCTest 框架正在释放一些内存池,因此 NSArray 被释放,但静态变量仍处于初始化状态。
除了在测试中重置onceToken之外,还有其他解决方案吗?
最佳答案
该测试暴露了 get
中的内存管理问题方法。自 arrayWithObjects:
返回一个自动释放的对象,在 MRC 下数组 _get
指向的值会在下次弹出自动释放池时被释放。要解决此问题,需要保留数组,方法是使用 initWithObjects:
分配它。或向 arrayWithObjects:
返回的对象发送一条保留消息.
关于objective-c - 由于dispatch_once导致XCTest失败的解决方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23307118/