Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Using assign to create weak references can be unsafe in a multithreaded system, particularly when either object can be retained by a third object, and then used to dereference the other object.</p> <p>Fortunately, this is often a problem of hierarchy, and the object containing the weak reference only cares about the object it refers to for the referred-to object's lifetime. This is the usual situation with a Superior&lt;->Subordinate relationship.</p> <p>I think that the case in the OP's comment maps to this, with Row = Superior, Block = Subordinate.</p> <p>In this case, I would use a handle to refer to the Superior from the Subordinate:</p> <pre><code>// Superior.h @class Superior; @interface SuperiorHandle : NSObject { @private Superior* superior_; } // note the deliberate avoidance of "nonatomic" @property (readonly) Superior *superior; @end @interface Superior : NSObject { @private SuperiorHandle *handle_; // add one or more references to Subordinate instances } // note the deliberate avoidance of "nonatomic" @property (readonly) SuperiorHandle *handle; @end // Superior.m #import "Superior.h" @implementation SuperiorHandle @synthesize superior = superior_; - (id)initWithSuperior:(Superior *)superior { if ((self = [super init])) { superior_ = superior; // weak reference } } - (void)invalidate { @synchronized (self) { superior_ = nil; } } - (Superior *)superior { @synchronized (self) { // retain and autorelease is required to prevent dealloc before we're ready, thanks to AndroidDev for pointing out this mistake return [[superior_ retain] autorelease]; } } @end @implementation Superior @synthesize handle = handle_; - (id)init { if ((self = [super init])) { handle_ = [[SuperiorHandle alloc] initWithSuperior:self]; } return self; } - (void)dealloc { [handle_ invalidate]; [handle_ release]; [super dealloc]; } @end // Subordinate.h @class Superior; @class SuperiorHandle; @interface Subordinate : NSObject { @private SuperiorHandle *superior_handle_; } @property (readonly) Superior *superior; @end // Subordinate.m #import "Subordinate.h" #import "Superior.h" @implementation Subordinate // no synthesize this time, superior's implementation is special - (id)initWithSuperior:(Superior *)superior { if ((self = [super init])) { superior_handle_ = [superior.handle retain]; } return self; } - (void)dealloc { [superior_handle_ release]; [super dealloc]; } - (Superior *)superior { @synchronized (superior_handle_) { return superior_handle_.superior; } } @end </code></pre> <p>Some advantages:</p> <ol> <li>It's thread safe. There is no way you can have the weak reference contained in Subordinate become an invalid pointer. It may become nil but that is OK.</li> <li>Only the objects themselves need to know about the embedded weak reference. All other objects can treat Subordinate as if it has a regular reference to Superior.</li> </ol>
 

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