From 6fdb9dfef2c10696fc38a3ad860e014782b7d698 Mon Sep 17 00:00:00 2001 From: "thomasvl@gmail.com" Date: Mon, 17 Nov 2008 21:30:25 +0000 Subject: - Added GTMLightweightProxy - Added installer for the spotlight importers. --- Foundation/GTMLightweightProxy.m | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 Foundation/GTMLightweightProxy.m (limited to 'Foundation/GTMLightweightProxy.m') diff --git a/Foundation/GTMLightweightProxy.m b/Foundation/GTMLightweightProxy.m new file mode 100644 index 0000000..ad7e0a1 --- /dev/null +++ b/Foundation/GTMLightweightProxy.m @@ -0,0 +1,112 @@ +// +// GTMLightweightProxy.m +// +// Copyright 2006-2008 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// + +#import "GTMLightweightProxy.h" + + +@implementation GTMLightweightProxy + +- (id)initWithRepresentedObject:(id)object { + // it's weak, we don't retain + representedObject_ = object; + return self; +} + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 +// -[NSProxy finalize] is only in 10.5 or later +- (void)finalize { + representedObject_ = nil; + [super finalize]; +} +#endif + +- (void)dealloc { + // it's weak, we don't release + representedObject_ = nil; + [super dealloc]; +} + +- (id)representedObject { + // Use a local variable to avoid a bogus compiler warning. + id repObject = nil; + @synchronized(self) { + // Even though we don't retain this object, we hang it on the lifetime + // of the calling threads pool so it's lifetime is safe for at least that + // long. + repObject = [[representedObject_ retain] autorelease]; + } + return repObject; +} + +- (void)setRepresentedObject:(id)object { + @synchronized(self) { + representedObject_ = object; + } +} + +// Passes any unhandled method to the represented object if it responds to that +// method. +- (void)forwardInvocation:(NSInvocation*)invocation { + id target = [self representedObject]; + // Silently discard all messages when there's no represented object + if (!target) + return; + + SEL aSelector = [invocation selector]; + if ([target respondsToSelector:aSelector]) + [invocation invokeWithTarget:target]; +} + +// Gets the represented object's method signature for |selector|; necessary for +// forwardInvocation. +- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector { + id target = [self representedObject]; + if (target) { + return [target methodSignatureForSelector:selector]; + } else { + // Apple's underlying forwarding code crashes if we return nil here. + // Since we are not going to use the invocation being constructed + // if there's no representedObject, a random valid NSMethodSignature is fine. + return [NSObject methodSignatureForSelector:@selector(alloc)]; + } +} + +// Prevents exceptions from unknown selectors if there is no represented +// object, and makes the exception come from the right place if there is one. +- (void)doesNotRecognizeSelector:(SEL)selector { + id target = [self representedObject]; + if (target) + [target doesNotRecognizeSelector:selector]; +} + +// Checks the represented object's selectors to allow clients of the proxy to +// do respondsToSelector: tests. +- (BOOL)respondsToSelector:(SEL)selector { + if ([super respondsToSelector:selector] || + selector == @selector(initWithRepresentedObject:) || + selector == @selector(representedObject) || + selector == @selector(setRepresentedObject:)) + { + return YES; + } + + id target = [self representedObject]; + return target && [target respondsToSelector:selector]; +} + +@end -- cgit v1.2.3