7

我遇到了一个问题,即我遇到了错误的访问异常,但仅在运行测试版本时(在调试版本中调用相同的方法不会导致问题出现)。该项目启用了 ARC,我正在使用 Xcode 4.3 在 iPad 5.1 模拟器上运行它:

这就是问题出现的地方:

- (void)testChangeFoodNotification {
    Player* p = [[Player alloc] init];
    [p addObserver:self forKeyPath:@"food" options:0 context:0]; // <-EXC_BAD_ACCESS (code=2)
    p.food += 1;
    STAssertTrue(_wasNotifiedOfFoodChange, nil);
}

addObserver:调用该方法时,似乎不应该释放任何涉及的对象,那么可能导致异常的原因是什么?

编辑:

抱歉,如果不清楚,但上面的代码正在作为测试用例的一部分执行(使用标准 Xcode OCUnit)。此外,如果它澄清了任何来自播放器类的相关代码(还有其他 ivars 和方法,但它们与正在测试的属性或方法没有任何联系):

// Public interface
@interface Player : NSObject

@property (nonatomic, assign) NSInteger food;

@end

// Private interface
@interface Player() {
    NSInteger _food;
}

@end

@implementation Player

@synthesize food = _food;

#pragma mark - Getters/Setters

- (void)setFood:(NSInteger)food {
    [self willChangeValueForKey:@"food"];
    _food = food;
    [self didChangeValueForKey:@"food"];    
}
4

2 回答 2

21

如果您的类确实符合键值对,请确保出现问题的类的实现不包含在您的测试产品中。这意味着您的 .m 文件的身份检查器的 Target Membership 面板应该只检查您的应用程序(而不是 YourAppTests)。

我在 Xcode 4.3.1 中遇到了同样的问题,当时两种产品都包含一个实现,并且我在生产和测试代码中都注册了观察者。以下日志提示我:

YourClass 类在 /Users/yourUser/Library/Application Support/iPhone Simulator/5.1/Applications//YourApp.app/YourApp 和 /Users/yourUser/Library/Developer/Xcode/DerivedData/YourApp-/Build/Products/ 中实现调试-iphonesimulator/YourAppTests.octest/YourAppTests。将使用两者之一。哪一个是未定义的。

于 2012-04-26T16:47:28.240 回答
0

根据Key-Value Observing Programming Guide,您的 Player 是否符合键值对?您要确保确保 KVC 合规性。我还假设您也实施了您的observeValueForKeyPath:ofObject:change:context:? 如果您认为您已经完成了所有这些但仍然无法正常工作,那么也许您可以分享您的代码。

另外,小事,但我认为这是一个突出问题的代码片段。我之所以提到它,是因为 ARC 将在您的 testChangeFoodNotification 结束时释放您的 p 对象,我原以为您想先删除您的观察者。

于 2012-04-20T13:31:12.013 回答