Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
ReleaseLockProxy.m
Go to the documentation of this file.
1/* ReleaseLockProxy.h
2 By Jens Ayton
3 This code is hereby placed in the public domain.
4*/
5
6#import "ReleaseLockProxy.h"
7
8
9#define VERBOSE 0
10
11#if VERBOSE
12#define VerboseLog NSLog
13#else
14#define VerboseLog(...) do {} while (0)
15#endif
16
17
19
20// These exist purely to provide NSMethodSignatures for -[ReleaseLockProxy methodSignatureForSelector:].
21+ (id)initWithObject:(id<NSObject>)object name:(NSString *)name;
22+ (id)initWithRetainedObject:(id<NSObject>)object name:(NSString *)name;
23+ (void)rlpAllowRelease;
24+ (NSString *)rlpObjectDescription;
25
26@end
27
28
29@implementation ReleaseLockProxy
30
31// *** Boilerplate
32
33+ (id)proxyWithObject:(id<NSObject>)object name:(NSString *)name
34{
35 return [[[self alloc] initWithObject:object name:name] autorelease];
36}
37
38
39+ (id)proxyWithRetainedObject:(id<NSObject>)object name:(NSString *)name
40{
41 return [[[self alloc] initWithRetainedObject:object name:name] autorelease];
42}
43
44
45- (id)initWithObject:(id<NSObject>)object name:(NSString *)name
46{
47 return [self initWithRetainedObject:[object retain] name:name];
48}
49
50
51- (id)initWithRetainedObject:(id<NSObject>)object name:(NSString *)name
52{
53 if (object == nil)
54 {
55 NSLog(@"** ReleaseLockProxy: passed nil object, returning nil proxy.");
56 [self release];
57 return nil;
58 }
59
60 // No super init for proxies.
61
62 _object = object;
63 _name = [name copy];
64 _locked = YES;
65
66 return self;
67}
68
69
70- (void)dealloc
71{
72 if (_locked)
73 {
74 NSLog(@"** ReleaseLockProxy (%@): deallocated while locked. This shouldn't happen, unless -dealloc is being called directly.", [self rlpObjectDescription]);
75 }
76 else
77 {
78 VerboseLog(@"-- ReleaseLockProxy (%@): deallocated while not locked.", [self rlpObjectDescription]);
79 }
80
81 [_object release];
82 [_name release];
83
84 [super dealloc];
85}
86
87
88- (void)rlpAllowRelease
89{
90 _locked = NO;
91}
92
93
94- (NSString *)rlpObjectDescription
95{
96 return _name ? _name : [_object description];
97}
98
99
100// *** Core functionality
101
102- (void)release
103{
104 unsigned retainCount = [self retainCount];
105
106 if (_locked && retainCount == 1)
107 {
108 // Breakpoint here to catch what would otherwise be the last release before crashing.
109 NSLog(@"** ReleaseLockProxy (%@): released while locked and retain count is one - intercepting retain. Something is broken.", [self rlpObjectDescription]);
110 return;
111 }
112
113 if (_locked)
114 {
115 VerboseLog(@"-- ReleaseLockProxy (%@): released while locked, but retain count > 1; retain count going from %u to %u.", [self rlpObjectDescription], retainCount, retainCount - 1);
116 }
117 else
118 {
119 VerboseLog(@"-- ReleaseLockProxy (%@): released while not locked; retain count going from %u to %u.", [self rlpObjectDescription], retainCount, retainCount - 1);
120 }
121
122 [super release];
123}
124
125
126- (id)autorelease
127{
128 VerboseLog(@"-- ReleaseLockProxy (%@): autoreleased while %slocked and retain count at %u.", [self rlpObjectDescription], _locked ? "" : "not ", [self retainCount]);
129 return [super autorelease];
130}
131
132
133// *** Proxy stuff.
134
135- (void)forwardInvocation:(NSInvocation *)invocation
136{
137 [invocation invokeWithTarget:_object];
138}
139
140
141- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
142{
143 NSMethodSignature *result = nil;
144
145 if (selector == @selector(initWithObject:name:) ||
146 selector == @selector(initWithRetainedObject:name:) ||
147 selector == @selector(rlpAllowRelease) ||
148 selector == @selector(rlpObjectDescription))
149 {
150 result = [ReleaseLockProxy_SignatureTemplateClass methodSignatureForSelector:selector];
151 }
152 else
153 {
154 result = [(id)_object methodSignatureForSelector:selector];
155 }
156
157 return result;
158}
159
160
161+ (BOOL)instancesRespondToSelector:(SEL)selector
162{
163 if (selector == @selector(initWithObject:name:) ||
164 selector == @selector(initWithRetainedObject:name:) ||
165 selector == @selector(rlpAllowRelease) ||
166 selector == @selector(rlpObjectDescription))
167 {
168 return YES;
169 }
170 else
171 {
172 return NO;
173 }
174}
175
176
177- (BOOL)respondsToSelector:(SEL)selector
178{
180}
181
182@end
183
184
186
187+ (id)initWithObject:(id<NSObject>)object name:(NSString *)name { return nil; }
188+ (id)initWithRetainedObject:(id<NSObject>)object name:(NSString *)name { return nil; }
189+ (void)rlpAllowRelease { }
190+ (NSString *)rlpObjectDescription { return nil; }
191
192@end
#define NSLog(format,...)
Definition OOLogging.h:137
return self
return nil
#define VerboseLog(...)
BOOL instancesRespondToSelector:(SEL selector)
NSString * rlpObjectDescription()
id< NSObject > _object