本文介绍了如何在ARC下获取OCMock以停止使用弱属性填充NSProxy子类集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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?

编辑:这似乎与OCMockObjectNSProxy有关,如果我将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子类集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 23:20