Line data Source code
1 0 : /* 2 : 3 : OOWeakReference.h 4 : 5 : Weak reference class for Cocoa/GNUstep/OpenStep. As it stands, this will not 6 : work as a weak reference in a garbage-collected environment. 7 : 8 : A weak reference allows code to maintain a reference to an object while 9 : allowing the object to reach a retain count of zero and deallocate itself. 10 : To function, the referenced object must implement the OOWeakReferenceSupport 11 : protocol. 12 : 13 : Client use is extremely simple: to get a weak reference to the object, call 14 : -weakRetain and use the returned proxy instead of the actual object. When 15 : finished, release the proxy. Messages sent to the proxy will be forwarded as 16 : long as the underlying object exists; beyond that, they will act exactly like 17 : messages to nil. (IMPORTANT: this means messages returning floating-point or 18 : struct values have undefined return values, so use -weakRefUnderlyingObject in 19 : such cases.) Example: 20 : 21 : @interface ThingWatcher: NSObject 22 : { 23 : @private 24 : Thing *thing; 25 : } 26 : @end 27 : 28 : @implementation ThingWatcher 29 : - (void)setThing:(Thing *)aThing 30 : { 31 : [thing release]; 32 : thing = [aThing weakRetain]; 33 : } 34 : 35 : - (void)frobThing 36 : { 37 : [thing frob]; 38 : } 39 : 40 : - (void)dealloc 41 : { 42 : [thing release]; 43 : [super dealloc]; 44 : } 45 : @end 46 : 47 : 48 : Note that the only reference to OOWeakReference being involved is the call to 49 : weakRetain instead of retain. However, the following would not work: 50 : thing = aThing; 51 : [thing weakRetain]; 52 : 53 : Additionally, it is not possible to access instance variables directly -- but 54 : then, that's a filthy habit. 55 : 56 : OOWeakReferenceSupport implementation is also simple: 57 : 58 : @interface Thing: NSObject <OOWeakReferenceSupport> 59 : { 60 : @private 61 : OOWeakReference *weakSelf; 62 : } 63 : @end 64 : 65 : @implementation Thing 66 : - (id)weakRetain 67 : { 68 : if (weakSelf == nil) weakSelf = [OOWeakReference weakRefWithObject:self]; 69 : return [weakSelf retain]; 70 : } 71 : 72 : - (void)weakRefDied:(OOWeakReference *)weakRef 73 : { 74 : if (weakRef == weakSelf) weakSelf = nil; 75 : } 76 : 77 : - (void)dealloc 78 : { 79 : [weakSelf weakRefDrop]; // Very important! 80 : [super dealloc]; 81 : } 82 : 83 : - (void)frob 84 : { 85 : NSBeep(); 86 : } 87 : @end 88 : 89 : 90 : Copyright (C) 2007-2013 Jens Ayton 91 : This code is hereby placed in the public domain. 92 : 93 : */ 94 : 95 : #import <Foundation/Foundation.h> 96 : #import "OOFunctionAttributes.h" 97 : 98 : @class OOWeakReference; 99 : 100 : 101 : @protocol OOWeakReferenceSupport <NSObject> 102 : 103 0 : - (id)weakRetain OO_RETURNS_RETAINED; // Returns a retained OOWeakReference, which should be released when finished with. 104 0 : - (void)weakRefDied:(OOWeakReference *)weakRef; 105 : 106 : @end 107 : 108 : 109 0 : @interface OOWeakReference: NSProxy 110 : { 111 0 : id<OOWeakReferenceSupport> _object; 112 : } 113 : 114 0 : - (id)weakRefUnderlyingObject; 115 : 116 0 : - (id)weakRetain OO_RETURNS_RETAINED; // Returns [self retain] for weakrefs. 117 : 118 : // For referred object only: 119 0 : + (id)weakRefWithObject:(id<OOWeakReferenceSupport>)object; 120 0 : - (void)weakRefDrop; 121 : 122 : @end 123 : 124 : 125 : @interface NSObject (OOWeakReference) 126 : 127 0 : - (id)weakRefUnderlyingObject; // Always self for non-weakrefs (and of course nil for nil). 128 : 129 : @end 130 : 131 : 132 : /* OOWeakRefObject 133 : Simple object implementing OOWeakReferenceSupport, to subclass. This 134 : provides a full implementation for simplicity, but keep in mind that the 135 : protocol can be implemented by any class. 136 : */ 137 0 : @interface OOWeakRefObject: NSObject <OOWeakReferenceSupport> 138 : { 139 : OOWeakReference *weakSelf; 140 0 : } 141 : 142 : - (id)weakSelf; // Equivalent to [[self weakRetain] autorelease] 143 0 : 144 : @end