我在结合 XCTest 使用键值观察逻辑时遇到了一些困难(原始代码正在通过测试覆盖率进行改造)。该逻辑在正常(非测试)上下文中运行良好,但每次在测试上下文中都会出现异常。
逻辑的要点是——我有两个类,分别称为 Service 和 Helper。脚手架的实现是:
interface Service : NSObject {
BOOL svcCallComplete;
}
@end
@implementation Service
- (id) init {
if ((self=[super init])==nil) {
return nil;
}
return self;
}
@end
interface Helper : NSObject {
}
@end
@implementation Helper
- (id) init {
if ((self=[super init])==nil) {
return nil;
}
return self;
}
@end
Helper 是 Service 中某个属性的观察者。在我的正常运行时逻辑的上下文中,我通过调用 Service 实例方法来做到这一点addSvcObserver
:
服务.m:
- (void) addSvcObserver:(id)observer {
[self addObserver:observer
forKeyPath:@"svcCallComplete"
options:NSKeyValueObservingOptionNew
context:nil];
}
Helper 遵循 KVO 观察模式,因此:
助手.m:
- (void) observeValueForKeyPath:(NSString*)keyPath
ofObject:(id)object
change:(NSDictionary*)change
context:(void*)context {
}
非常直截了当,我不会进入监视属性更改的逻辑,因为问题发生在此之前 - 如果我有如下代码摘录:
Service* service = [[Service alloc] init];
Helper* helper = [[Helper alloc] init];
[service addSvcObserver:helper];
在非测试用例中没有问题(即,这个和相关的 KVO 逻辑按预期工作)。但是,addSvcObserver
在 XCTest 测试方法的上下文中执行调用时会立即产生拒绝访问异常。我已经包含了一个异常“全部中断”断点——问题似乎发生objc_registerClassPair
在addObserver:forKeyPath:options:context:
。测试目标明确禁用了 ARC,因为它提供测试覆盖的项目(目标是 iOS7)由于遗留原因是非 ARC;这似乎不会对其他测试造成任何问题。
想法?