NSProxy 如何“将自身转变为另一个对象”?

发布于 2024-11-28 16:16:54 字数 583 浏览 5 评论 0原文

NSProxy 类参考< /a> 说的是:

通常,发送给代理的消息会转发到真实对象,或者导致代理加载(或将其自身转换为)真实对象。

“变形为实物”到底是如何进行的呢?

为了让事情更具体一些,假设类 Foo 有一个方法 newFooWithString:,它接受一个字符串并返回 Foo 的新实例。是否可以设置一个位于周围的 NSProxy,如果收到 pleaseBecomeAFooUsingString: @"bar" 消息,则将其自身转换为 [Foo newFooWithString: @ “bar”],占用相同的内存,而不与可能存在的其他对其自身的引用混淆?

The NSProxy Class Reference says this:

Typically, a message to a proxy is forwarded to the real object or causes the proxy to load (or transform itself into) the real object.

How exactly would the "transform itself into the real object" work?

To make things a little more specific, suppose class Foo has a method newFooWithString: that takes a string and returns a new instance of Foo. Would it be possible to setup an NSProxy that sits around, and if a pleaseBecomeAFooUsingString: @"bar" message is received, transforms itself into [Foo newFooWithString: @"bar"], occupying the same memory, without messing with other references to itself that may exist?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白况 2024-12-05 16:16:54

如果您在整个代码中都有一个指向同一个 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 是一个简单的消息转发器,根本没有任何魔法,所以你的目标无法以你所描述的方式实现。

If you have a pointer to the same NSProxy instance all over the code and will "transform" it, it will change all over the code. There is no way to differentiate a caller of a method for an object, so you will not be able to alternate targets for forwarding of methods invocation in your code automatically. Common transformable proxy will looks in following way:

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

So what you requested is some sort of code-magic, but NSProxy is a simple forwarder of a messages, there is no any magic at all, so your goal is not achievable in a way as you described.

凝望流年 2024-12-05 16:16:54

您可以创建 NSProxy 的子类,该子类根据您想要的每个标准来更改将其方法转发到的对象。因此,您的对象将始终指向 NSProxy,但您 pleaseBecomeAFooUsingString: 会将其转发到的对象更改为 Foo。

You could create a subclass of of NSProxy that changes which object it forwards it methods to based of what every criteria you want. So you object will always point to NSProxy but you pleaseBecomeAFooUsingString: will change the the object it forwards to as a Foo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文