Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I get OCMock under ARC to stop nilling an NSProxy subclass set using a weak property?
    primarykey
    data
    text
    <p>Under <code>ARC</code>, I have an object, <code>Child</code> that has a <code>weak</code> property, <code>parent</code>. I'm trying to write some tests for <code>Child</code>, and I'm mocking its <code>parent</code> property using <code>OCMock</code>.</p> <p>Under ARC, setting an <code>NSProxy</code> 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 <code>nil</code>. Here's the concrete example:</p> <pre><code>@interface Child : NSObject @property (nonatomic, weak) id &lt;ParentInterface&gt;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&lt;ParentInterface&gt;)aParent; assertThat([child parent], notNilValue()); // &lt;-- This assertion fails [aParent self]; // &lt;-- Added this reference just to ensure `aParent` was valid until the end of the test. } </code></pre> <p>I know that I can get around this using an <code>assign</code> property instead of a <code>weak</code> property for the <code>Child</code> to reference the <code>Parent</code>, but then I'd have to <code>nil</code> out the <code>parent</code> when I was done with it (like some sort of caveman), which is exactly the sort of thing that ARC was supposed to obviate.</p> <p>Any suggestions on how to make this test pass without changing my app code?</p> <p><strong>Edit</strong>: It seems to have to do with <code>OCMockObject</code> being an <code>NSProxy</code>, if I make <code>aParent</code> be an instance of <code>NSObject</code>, the <code>child.parent</code> weak reference "holds" a non-nil value. Still looking for a way to make this test pass without changing app code.</p> <p><strong>Edit 2</strong>: 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:</p> <pre><code>#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 </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload