Heads up: это странный вопрос.
У меня есть несколько действительно полезных макросов, которые я хотел бы использовать для упрощения ведения журнала. Например, я могу сделать Log(@"My message with arguments: %@, %@, %@", @"arg1", @"arg2", @"arg3")
, и это будет расширено до более сложного вызова метода, который включает в себя такие вещи, как self
, _cmd
, __FILE__
, __LINE__
и т. Д., Чтобы я мог легко отслеживать, где что-то регистрируются. Это прекрасно работает.
Теперь я хотел бы расширить свои макросы, чтобы они работали не только с методами Objective-C, но и с общими функциями C. Проблема заключается в частях self
и _cmd
, которые находятся в расширении макроса. Эти два параметра не существуют в функциях C. В идеале я хотел бы иметь возможность использовать этот же набор макросов в функциях C, но у меня возникают проблемы. Когда я использую (например) мой макрос Log()
, я получаю предупреждения компилятора о необъявлении self
и _cmd
(что имеет смысл).
Моей первой мыслью было сделать что-то вроде следующего (в моем макросе):
if (thisFunctionIsACFunction) {
DoLogging(nil, nil, format, ##__VA_ARGS__);
} else {
DoLogging(self, _cmd, format, ##__VA_ARGS__);
}
Это по-прежнему выдает предупреждения компилятора, поскольку вместо макроса заменяется весь оператор if (), что приводит к ошибкам с ключевыми словами self
и _cmd
(даже если они никогда не будут выполняться во время выполнения функции).
Моей следующей мыслью было сделать что-то вроде этого (в моем макросе):
if (thisFunctionIsACFunction) {
#define SELF nil
#define CMD nil
} else {
#define SELF self
#define CMD _cmd
}
DoLogging(SELF, CMD, format, ##__VA_ARGS__);
Это не работает, к сожалению. На моем первом #define
.
появляется сообщение об ошибке: «#» не сопровождается параметром макроса ».
Другой моей мыслью было создание второго набора макросов, специально для использования в функциях Си. Это пахнет плохим запахом кода, и я действительно не хочу этого делать.
Можно ли как-то использовать один и тот же набор макросов как в методах Objective-C, так и в функциях C, и ссылаться только на self
и _cmd
, если макрос используется в методе Objective-C?
edit больше информации:
thisFunctionIsACFunction
определяется довольно элементарно (и я определенно открыт для улучшений и предложений). В основном это так:
BOOL thisFunctionIsACFunction == (__PRETTY_FUNCTION__[0] != '-' && __PRETTY_FUNCTION__[0] != '+');
Он полагается на поведение компилятора, добавляющего «-» или «+» для методов экземпляра и класса к объектам Objective-C. Все остальное должно быть функцией C (поскольку функции C не могут иметь имен, начинающихся с '-' или '+').
Я понимаю, что эта проверка технически является проверкой во время выполнения, поскольку __PRETTY_FUNCTION__
заменяется на char*
, и это, вероятно, является основным препятствием для моего запроса о помощи.