12

NSProxy クラス リファレンスには次のように書かれています。

通常、プロキシへのメッセージは実際のオブジェクトに転送されるか、プロキシに実際のオブジェクトをロード (またはプロキシ自体を変換) させます。

「自分自身を現実の物体に変換する」とは具体的にどのように機能するのでしょうか?

もう少し具体的に説明すると、文字列を受け取って の新しいインスタンスを返すFooメソッドが class にあるとします。存在する可能性のあるそれ自体への他の参照をいじることなく、同じメモリを占有し、メッセージが受信された場合に自身を に変換する をセットアップすることは可能でしょうか?newFooWithString:FooNSProxypleaseBecomeAFooUsingString: @"bar"[Foo newFooWithString: @"bar"]

4

2 に答える 2

6

コード全体に同じ NSProxy インスタンスへのポインタがあり、それを「変換」すると、コード全体が変更されます。オブジェクトのメソッドの呼び出し元を区別する方法がないため、コード内のメソッド呼び出しの転送先を自動的に切り替えることはできません。一般的な変換可能なプロキシは次のようになります。

MyTrickyProxy.h

#import <Foundation/Foundation.h>

@interface MyTrickyProxy : NSProxy {
    NSObject *object;
}

- (id)transformToObject:(NSObject *)anObject;

@end

MyTrickyProxy.m

#import "MyTrickyProxy.h"

@implementation MyTrickyProxy

- (void)dealloc 
{
    [object release];
    object = nil;

    [super dealloc];
}

- (NSString *)description 
{
    return [object description];
}

//Stupid transform implementation just by assigning a passed in object as transformation target. You can write your factory here and use passed in object as id for object that need ot be created.
- (id)transformToObject:(NSObject *)anObject 
{
    if(object != anObject) {
        [object release];
    }
    object = [anObject retain];

    return object;
}

- (void)forwardInvocation:(NSInvocation *)invocation 
{
    if (object != nil) {
        [invocation setTarget:object];    
        [invocation invoke];
    }
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel 
{
    NSMethodSignature *result;
    if (object != nil) {
        result = [object methodSignatureForSelector:sel];
    } else {
        //Will throw an exception as default implementation
        result = [super methodSignatureForSelector:sel];
    }

    return result;
}

@end

あなたが要求したのはある種のコードマジックですが、NSProxyはメッセージの単純なフォワーダーであり、魔法はまったくないため、あなたが説明した方法では目標を達成できません.

于 2011-08-07T02:56:22.800 に答える
0

必要なすべての基準に基づいて、メソッドを転送するオブジェクトを変更する NSProxy のサブクラスを作成できます。したがって、オブジェクトは常に NSProxy を指しますが、pleaseBecomeAFooUsingString: は転送先のオブジェクトを Foo に変更します。

于 2011-08-07T22:32:41.550 に答える