【问题标题】:Is there a way to observe every message calls invoked on an object (iOS)?有没有办法观察对象(iOS)上调用的每个消息调用?
【发布时间】:2012-06-28 13:02:02
【问题描述】:

我只想在每次向对象发送消息时获取选择器名称、参数、发送者或 NSInvocation 实例。可能的?类似于 forwardInvocation:,但在每种情况下(每个方法调用)。

【问题讨论】:

    标签: ios selector nsinvocation message-forwarding


    【解决方案1】:

    有一种方法可以通过在 Objective-C 消息传递中使用隐藏参数来获取选择器的名称和目标。来自Apple's documentation

    当 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:即使这不能回答你的问题,也可以为这个问题 +1.. 真的让我想到了这个。

    【讨论】:

    • 我试图在没有实际使用Helperclass 的情况下实现某些目标,但似乎不可行。
    【解决方案2】:

    所以我做了这门课,就像一个魅力。

    .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。

    【讨论】:

    • Geri,你能说说它的实际用途吗? :)
    • 为给定应用创建远程连接镜像应用。应该在对等设备上调用许多方法(不知道实际的消息/任务)。
    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多