简短说明:
NSDictionary 中的一个对象似乎被过度释放。涉及对象新功能的调配,并被认为是导致问题的原因。
长解释:
我正在为没有考虑单元测试的代码开发一些单元测试。为了用模拟对象替换代码中创建的对象,我使用了 swizzling。
我最近进行了以下设置:
- 我有一个单例测试类,它基本上只包含一个测试数据字典。
- 我有一个测试用例,它创建一个模拟对象(MockA),该对象应通过 swizzling 发送到测试函数,运行被测函数并检查结果。
- 我有一个清理阶段
现在来一些代码:
测试用例(注意崩溃!!)
- (void)testLogin
{
[self swizzleLoginOperation];
MockLoginOperation* op = [MockLoginOperation new];
// *** op setup code here ***
[[TestSingleton sharedInstance].dataToShare setObject:op forKey:LOGIN_OPERATION];
// pseudo-code below
[classUnderTestInstance login];
// Assert something
// Cleanup
[self swizzleLoginOperation];
[[TestSingleton sharedInstance].dataToShare removeAllObjects]; // Crash!!
}
调酒功能
- (void)swizzleLoginOperation
{
Method origMethod = class_getClassMethod([LoginOperation class], @selector(new));
Method newMethod = class_getClassMethod([MockLoginOperation class], @selector(createLoginOperationTest));
c = object_getClass((id)[LoginOperation class]);
if(class_addMethod(c, origSel, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
{
class_replaceMethod(c, newSel, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
}
else
{
method_exchangeImplementations(origMethod, newMethod);
}
}
+ (LoginOperation*)createLoginOperationTest
{
NSDictionary* values = [TestSingleton sharedInstance].dataToShare;
LoginOperation* op = (LoginOperation*)[values objectForKey:LOGIN_OPERATION];
return op;
}
被测功能
- (void)login
{
LoginOperation* op = [LoginOperation new];
// More stuff which I have removed but still get the problem
}
有任何想法吗?
更新
为了找到错误,我尝试运行此代码:
for (NSString* key in self.dataToShare.allKeys)
{
NSObject* value = [self.dataToShare objectForKey:key]; // Crashes here
}
崩溃线程 1: EXC_BAD_ACCESS(code=1, address=...) 在日志中: *** -[MockLoginOperation retain]: message sent to deallocated instance 0x7fd7b31f5050