Печать аргументов, отправленных на forwardInvocation: подкласс NSProxy - PullRequest
0 голосов
/ 29 ноября 2009

Я хочу перехватывать сообщения, отправленные прокси-объекту, просто печатая селектор и аргументы. Даже если прокси не реализует их и не имеет целевого объекта. Пожалуйста помоги. Я рассмотрел несколько вариантов и документы Apple, но они предполагают, что вы уже знаете целевой объект. Я хочу сделать это чисто без проблем с памятью.

 @implementation MyProxy

    -(void)forwardInvocation:(NSInvocation*)anInvocation
        {

        // at this point I would

         //like to fetch the arguments and put on an array 
         NSMutableArray *myArgs = .....;
         NSLog(@"Invoking selector %@", theSelector);
         NSLog (myArgs); // this should print me the list of arguments to the method
        }
@end
         // e.g 
            MyProxy *proxy = [[MyProxy alloc] init];
            [proxy SendMeAnyThing: @"hello"]; // this should print me arguments 
        or [proxy add: 12 to: 89 sub: 89]; // should print the arguments

Спасибо, спасибо

1 Ответ

3 голосов
/ 29 ноября 2009

Аргументы относятся практически к любому типу C, включая типы Objective-C, которые могут быть переданы методу. Таким образом, они не могут быть представлены в массиве.

Обратите внимание, что вызывать метод, который нигде не объявлен, не имеет никакого смысла. В частности, компилятор не имеет представления о том, как кодировать аргументы на сайте вызова, чтобы сделать правильный вызов функции C (вызов метода на самом деле является просто вызовом функции C для objc_msgSend() или ее варианта). Итак, чтобы ответить на ваш вопрос «любой метод, даже если он не существует»; нет, ты не можешь этого сделать.

Однако вы можете эффективно исключить все предупреждения компилятора. Если вы исключите все предупреждения компилятора - все предупреждения типа «метод foo: bar: has not found» - тогда это означает, что компилятор имеет достаточно информации, и вы можете делать все, что захотите с прокси.

Кроме того (как я прочитал в вашем вопросе), нет необходимости реализовывать какие-либо методы на прокси. Прокси может с радостью пересылать вызовы NSInvocation любым вызовам методов. Правильно написанное, вы можете использовать прокси для любого объекта без проблем.

Что вам нужно сделать, это перечислить аргументы, используя API NSInvocation, выяснить типы, а затем соответствующим образом декодировать каждый аргумент и распечатать соответствующим образом.

Количество аргументов можно получить, вызвав numberOfArguments в сигнатуре метода экземпляра NSInvocation (подпись можно получить с помощью метода methodSignature).

Затем переберите аргументы и вызовите getArgumentTypeAtIndex: в сигнатуре метода, чтобы получить тип. Затем вы, скорее всего, напишите оператор switch() в кодировке типов, чтобы затем вызвать getArgument:atIndex: и декодировать соответствующим образом в зависимости от типа.

Обратите внимание, что аргумент 0 - это self, а аргумент 1 - _cmd; SEL метода, который был вызван.

...