2012-06-28 2 views
3

Я просто хочу получить имя селектора, аргументы, отправитель или экземпляр NSInvocation каждый раз при отправке сообщения объекту. Возможное? Что-то вроде forwardInvocation :, но в случае evey (каждый вызов метода).Есть ли способ наблюдать за каждым вызовом сообщений, вызываемым на объекте (iOS)?

ответ

4

Существует способ получить имя и цель селектора, используя скрытые параметры в сообщениях цели-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. Приложение должно потерпеть крах, но затем просто добавьте forwardInvocation: на класс Helper. Оттуда вы сможете получить объект NSInvocation. Сделайте то, что вам нужно сделать, а затем: [anInvocation invokeWithTarget:myClassReference];, чтобы вы могли передать сообщение первому абоненту.

P.S: Даже если это не отвечает на вопрос, +1 за вопрос .. На самом деле меня думать об этом.

+0

Эй, я обожаю обходной путь с «промежуточным» объектом! – Geri

+0

Это действительно здорово! – Geri

+0

Я займусь этим прямо сейчас. – Geri

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 insted of self.

+0

Гери, не могли бы вы сказать о ее практической цели? :) – Peres

+0

Создайте удаленно подключенное зеркальное приложение данного приложения. Многие методы должны вызываться на одноранговом устройстве (не зная фактических сообщений/задач). – Geri

 Смежные вопросы

  • Нет связанных вопросов^_^