问题描述
在ARC
下,我有一个对象Child
,它具有一个weak
属性parent
.我正在尝试为Child
编写一些测试,并且正在使用OCMock
模拟其parent
属性.
Under ARC
, I have an object, Child
that has a weak
property, parent
. I'm trying to write some tests for Child
, and I'm mocking its parent
property using OCMock
.
在ARC下,使用综合的弱属性设置器设置NSProxy
子类不会设置该属性...设置弱属性后的行,检查它是否已经存在nil
.这是具体示例:
Under ARC, setting an NSProxy
subclass using a synthesized weak property setter doesn't set the property ... the line after the weak property is set, checking it reveals that it's already nil
. Here's the concrete example:
@interface Child : NSObject
@property (nonatomic, weak) id <ParentInterface>parent;
@end
@implementation Child
@synthesize parent = parent_;
@end
// ... later, inside a test class ...
- (void)testParentExists
{
// `mockForProtocol` returns an `NSProxy` subclass
//
OCMockObject *aParent = [OCMockObject mockForProtocol:@protocol(ParentInterface)];
assertThat(aParent, notNilValue());
// `Child` is the class under test
//
Child *child = [[Child alloc] init];
assertThat(child, notNilValue());
assertThat(child.parent, nilValue());
child.parent = (id<ParentInterface>)aParent;
assertThat([child parent], notNilValue()); // <-- This assertion fails
[aParent self]; // <-- Added this reference just to ensure `aParent` was valid until the end of the test.
}
我知道我可以使用assign
属性而不是weak
属性来解决此问题,以便Child
引用Parent
,但是然后我必须nil
移出当我用完它(像某种穴居人)后,这正是ARC应该避免的事情.
I know that I can get around this using an assign
property instead of a weak
property for the Child
to reference the Parent
, but then I'd have to nil
out the parent
when I was done with it (like some sort of caveman), which is exactly the sort of thing that ARC was supposed to obviate.
关于在不更改我的应用代码的情况下如何通过此测试的任何建议?
Any suggestions on how to make this test pass without changing my app code?
编辑:这似乎与OCMockObject
是NSProxy
有关,如果我将aParent
用作NSObject
的实例,则child.parent
弱引用将成立"非零值.仍在寻找一种无需更改应用代码即可通过此测试的方法.
Edit: It seems to have to do with OCMockObject
being an NSProxy
, if I make aParent
be an instance of NSObject
, the child.parent
weak reference "holds" a non-nil value. Still looking for a way to make this test pass without changing app code.
编辑2 :在接受了布雷克的回答后,我在我的项目中实现了一个预处理器宏,该宏有条件地将属性从弱->分配更改为弱.您的里程可能会有所不同:
Edit 2: After accepting Blake's answer, I did an implementation in my project of a preprocessor macro that conditionally changed my properties from weak -> assign. Your mileage may vary:
#if __has_feature(objc_arc)
#define BBE_WEAK_PROPERTY(type, name) @property (weak, nonatomic) type name
#else
#define BBE_WEAK_PROPERTY(type, name) @property (assign, nonatomic) type name
#endif
推荐答案
我们一直在努力解决同一问题,这确实与ARC和对NSProxy派生对象的弱引用之间的不兼容有关.我建议使用预处理程序指令有条件地编译要在测试套件中分配的弱委托引用,以便您可以通过OCMock对其进行测试.
We've been struggling with this same issue and it does indeed have to do with an incompatibility between ARC and weak references to NSProxy derived objects. I would recommend using a pre-processor directive to conditionally compile your weak delegate references to assign within the test suite so you can test them via OCMock.
这篇关于如何在ARC下获取OCMock以停止使用弱属性填充NSProxy子类集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!