PageRenderTime 33ms CodeModel.GetById 17ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/google-toolbox-for-mac/Foundation/GTMLightweightProxy.m

http://macfuse.googlecode.com/
Objective C | 108 lines | 59 code | 14 blank | 35 comment | 10 complexity | 020c979b8d50a753829c137de6eb8916 MD5 | raw file
  1//
  2//  GTMLightweightProxy.m
  3//
  4//  Copyright 2006-2008 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9// 
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11// 
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18
 19#import "GTMLightweightProxy.h"
 20#import "GTMDefines.h"
 21
 22@implementation GTMLightweightProxy
 23
 24- (id)initWithRepresentedObject:(id)object {
 25  // it's weak, we don't retain
 26  representedObject_ = object;
 27  return self;
 28}
 29
 30- (id)init {
 31  return [self initWithRepresentedObject:nil];
 32}
 33
 34- (void)dealloc {
 35  // it's weak, we don't release
 36  representedObject_ = nil;
 37  [super dealloc];
 38}
 39
 40- (id)representedObject {
 41  // Use a local variable to avoid a bogus compiler warning.
 42  id repObject = nil;
 43  @synchronized(self) {
 44    // Even though we don't retain this object, we hang it on the lifetime
 45    // of the calling threads pool so it's lifetime is safe for at least that
 46    // long.
 47    repObject = [representedObject_ retain];
 48  }
 49  return [repObject autorelease];
 50}
 51
 52- (void)setRepresentedObject:(id)object {
 53  @synchronized(self) {
 54    representedObject_ = object;
 55  }
 56}
 57
 58// Passes any unhandled method to the represented object if it responds to that
 59// method.
 60- (void)forwardInvocation:(NSInvocation*)invocation {
 61  id target = [self representedObject];
 62  // Silently discard all messages when there's no represented object
 63  if (!target)
 64    return;
 65
 66  SEL aSelector = [invocation selector];
 67  if ([target respondsToSelector:aSelector])
 68    [invocation invokeWithTarget:target];
 69}
 70
 71// Gets the represented object's method signature for |selector|; necessary for
 72// forwardInvocation.
 73- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector {
 74  id target = [self representedObject];
 75  if (target) {
 76    return [target methodSignatureForSelector:selector];
 77  } else {
 78    // Apple's underlying forwarding code crashes if we return nil here.
 79    // Since we are not going to use the invocation being constructed
 80    // if there's no representedObject, a random valid NSMethodSignature is fine.
 81    return [NSObject methodSignatureForSelector:@selector(alloc)];
 82  }
 83}
 84
 85// Prevents exceptions from unknown selectors if there is no represented
 86// object, and makes the exception come from the right place if there is one.
 87- (void)doesNotRecognizeSelector:(SEL)selector {
 88  id target = [self representedObject];
 89  if (target)
 90    [target doesNotRecognizeSelector:selector];
 91}
 92
 93// Checks the represented object's selectors to allow clients of the proxy to
 94// do respondsToSelector: tests.
 95- (BOOL)respondsToSelector:(SEL)selector {
 96  if ([super respondsToSelector:selector] ||
 97      selector == @selector(initWithRepresentedObject:) ||
 98      selector == @selector(representedObject) ||
 99      selector == @selector(setRepresentedObject:))
100  {
101    return YES;
102  }
103
104  id target = [self representedObject];
105  return target && [target respondsToSelector:selector];
106}
107
108@end