Target.m
author Jens Alfke <jens@mooseyard.com>
Thu Mar 20 09:05:58 2008 -0700 (2008-03-20)
changeset 1 e55a17cdabd2
parent 0 d84d25d6cdbb
child 7 59addced5e2a
permissions -rw-r--r--
Configurable logging (LogTo).
Added "my_" prefix to category method names.
Added MurmurHash.
Added UniqueWindowController.
Bug fixes.
jens@0
     1
//
jens@0
     2
//  Target.m
jens@0
     3
//  MYUtilities
jens@0
     4
//
jens@0
     5
//  Created by Jens Alfke on 2/11/08.
jens@0
     6
//  Copyright 2008 Jens Alfke. All rights reserved.
jens@0
     7
//
jens@0
     8
jens@0
     9
#import "Target.h"
jens@0
    10
jens@0
    11
jens@0
    12
NSInvocation* _mktarget( id rcvr, SEL action )
jens@0
    13
{
jens@0
    14
    NSMethodSignature *sig = [rcvr methodSignatureForSelector: action];
jens@0
    15
    CAssert(sig,@"%@<%p> does not respond to %@",[rcvr class],rcvr,NSStringFromSelector(action));
jens@0
    16
    CAssert(sig.numberOfArguments==3,
jens@0
    17
           @"-[%@ %@] can't be used as a target because it takes >1 param",
jens@0
    18
           [rcvr class],NSStringFromSelector(action));
jens@0
    19
    CAssert(0==strcmp([sig getArgumentTypeAtIndex: 2],"@"),
jens@0
    20
           @"-[%@ %@] can't be used as a target because it takes a non-object param",
jens@0
    21
           [rcvr class],NSStringFromSelector(action));
jens@0
    22
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sig];
jens@0
    23
    inv.target = rcvr;
jens@0
    24
    inv.selector = action;
jens@0
    25
    return inv;
jens@0
    26
}
jens@0
    27
jens@0
    28
jens@0
    29
id $calltarget( NSInvocation *target, id param )
jens@0
    30
{
jens@1
    31
    id result = nil;
jens@0
    32
    if( target && target.target ) {
jens@1
    33
        [target retain];
jens@1
    34
        @try{
jens@1
    35
            [target setArgument: &param atIndex: 2];
jens@1
    36
            [target invoke];
jens@1
    37
            
jens@1
    38
            NSMethodSignature *sig = target.methodSignature;
jens@1
    39
            NSUInteger returnLength = sig.methodReturnLength;
jens@1
    40
            if( returnLength==0 ) {
jens@1
    41
                result = nil; // void
jens@0
    42
            } else {
jens@1
    43
                const char *returnType = sig.methodReturnType;
jens@1
    44
                if( returnType[0]=='@' ) {
jens@1
    45
                    [target getReturnValue: &result];
jens@1
    46
                } else {
jens@1
    47
                    UInt8 returnBuffer[returnLength];
jens@1
    48
                    [target getReturnValue: &returnBuffer];
jens@1
    49
                    result = [NSValue valueWithBytes: &returnBuffer objCType: returnType];
jens@1
    50
                }
jens@0
    51
            }
jens@1
    52
        }@finally{
jens@1
    53
            [target release];
jens@0
    54
        }
jens@1
    55
    }
jens@1
    56
    return result;
jens@0
    57
}