有没有一种方法可以观察在对象上调用的每个消息 (iOS)?

3
每当我向对象发送消息时,我只想获取选择器名称、参数、发送者或一个NSInvocation实例。有可能吗?类似于forwardInvocation:,但是在每种情况下(每个方法调用)都可以使用。
2个回答

4
使用objective-c消息中的隐藏参数可以获取选择器名称和目标。来自苹果文档

当objc_msgSend查找实现方法的过程时,它调用该过程并将消息中的所有参数传递给它。还会传递两个隐藏参数:

接收对象 方法的选择器

因此,在方法中您可以获得以下内容:

   id  target = getTheReceiver();
   SEL method = getTheMethod();

如果这些还不够满足您的需求,您可以按照以下步骤操作:
1. 创建一个名为“Helper”的类。 2. 从需要调用方法的类中引用该类,格式为:id <HelperDelegate> myClassReference; 3. 当您需要创建一个 [self method] 时,创建该 Helper 类的实例并在其上调用该方法,例如 [helper method]; 并添加 [helper setMyClassReference:self]; 4. 应用程序将崩溃,但随后只需在 Helper 类上添加 forwardInvocation: 方法。从那里,您将能够获取 NSInvocation 对象。做你需要做的事情,然后使用 [anInvocation invokeWithTarget:myClassReference]; 将消息传递给原始调用者。
P.S:即使这不能回答您的问题,也要点赞。它确实让我思考了一下。

我一直试图在不使用 Helper 类的情况下实现某些事情,但似乎不可行。 - Rui Peres

1

所以我创建了这个类,运行得非常好。

.h

@protocol PGMessageObserverDelegate
-(void)observedInvocation:(NSInvocation*) invocation willSendToObject:(id) object;
-(void)observedInvocation:(NSInvocation*) invocation didSendToObject:(id) object;
@end


@interface PGMessageObserver : NSObject

@property (nonatomic, readonly) id observable;
@property (nonatomic, readonly) id <PGMessageObserverDelegate> delegate;

+(id)messageObserverObserving:(id) observable delegate:(id) delegate;

@end

.m

#import "PGMessageObserver.h"


@interface PGMessageObserver ()
-(id)initWithObservable:(id) observable delegate:(id) delegate;
@end


@implementation PGMessageObserver
@synthesize observable = _observable;
@synthesize delegate = _delegate;



#pragma mark - Creation

+(id)messageObserverObserving:(id) observable delegate:(id) delegate
{
    return [[[PGMessageObserver alloc] initWithObservable:observable delegate:delegate] autorelease];
}

-(id)initWithObservable:(id) observable delegate:(id) delegate
{
    if (self = [super init])
    {
        _observable = observable;
        _delegate = delegate;
    }
    return self;
}


#pragma mark - Message forwarding

-(void)forwardInvocation:(NSInvocation*) invocation
{
    //Notify.
    [_delegate observedInvocation:invocation willSendToObject:_observable];

        //Forward.
        if (_observable != nil)
        {
            [invocation invokeWithTarget:_observable];

            //Notify.
            [_delegate observedInvocation:invocation didSendToObject:_observable];
        }
}

-(NSMethodSignature*)methodSignatureForSelector:(SEL) selector
{
    return [_observable methodSignatureForSelector:selector];
}

@end

它并不像可能会那样严格,但它会通知我有关发送到此观察者的每个操作,并将消息重定向到原始对象(可观察对象)。

客户端代码只是一个保留属性...

@property (nonatomic, retain) PGMessageObserver *messageObserver;
#define self_OBSERVED _messageObserver

...还有一个设置在某个地方。

self.messageObserver = [PGMessageObserver messageObserverObserving:self delegate:self];

应该将可观察的消息发送到SELF_OBSERVED而不是self。


Geri,你能告诉我它的实际用途吗?:) - Rui Peres
创建一个连接到远程应用程序的镜像应用程序。许多方法应该在对等设备上调用(而不知道实际的消息/任务)。 - Geri Borbás

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接