3

オブジェクトにメッセージを送信するたびに、セレクター名と、引数、送信者、またはNSInvocationインスタンスを取得したいだけです。可能?forwardInvocation:のようなものですが、すべての場合(すべてのメソッド呼び出し)。

4

2 に答える 2

4

Objective-Cメッセージングで非表示のパラメーターを使用して、セレクターの名前とターゲットを取得する方法があります。Appleのドキュメントから:

objc_msgSendは、メソッドを実装するプロシージャを見つけると、そのプロシージャを呼び出して、メッセージ内のすべての引数を渡します。また、プロシージャに2つの隠された引数を渡します。

受信オブジェクトメソッドのセレクター

したがって、メソッドでは、次のようになります。

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

それでもニーズに対応できない場合は、次の手順を実行できます。

  1. というクラスを作成しますHelper
  2. 次の形式で、メソッドを呼び出すクラスへの参照を追加します。id <HelperDelegate> myClassReference;
  3. [self method]代わりに、このHelperクラスのインスタンスを作成し、そのメソッドを次のように呼び出して、[helper method];これを追加する必要がある場合[helper setMyClassReference:self];
  4. forwardInvocation:アプリがクラッシュするはずですが、Helperクラスにを追加するだけです。そこから、NSInvocationオブジェクトを取得できるようになります。必要なことを実行して[anInvocation invokeWithTarget:myClassReference];から、元の発信者にメッセージを渡すことができるようにします。

PS:これであなたの質問に答えられなくても、質問に+1してください。本当にこれについて考えさせられました。

于 2012-06-28T13:32:03.773 に答える
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 ではなく SELF_OBSERVED に送信する必要があります。

于 2012-06-28T14:26:09.880 に答える