Я нашел решение, которое работает для меня довольно хорошо.Сначала просто уточнить, что я не смог найти простой (и быстрый по быстродействию) способ автоматической генерации подходящих методов swizzled для произвольных селекторов (то есть с произвольными аргументами и возвращаемым значением), используя только имя селектора.Поэтому мне пришлось добавить типы аргументов и возвращаемое значение для каждого селектора, а не только имя селектора.В действительности должно быть относительно легко создать небольшой инструмент, который сможет анализировать все исходные файлы и автоматически определять типы аргументов и возвращаемое значение селектора, который мы хотим профилировать (и подготовить методы swizzled), но правильнотеперь мне не нужно такое автоматизированное решение.
Так что сейчас мое решение включает в себя вышеупомянутые идеи для метода swizzling, некоторый код C ++ и макросы для автоматизации и минимизации некоторого кодирования.
Сначала здесьпростой класс C ++, который измеряет время
class PerfTimer
{
public:
PerfTimer(PerfProfiledDataCounter* perfProfiledDataCounter);
~PerfTimer();
private:
uint64_t _startTime;
PerfProfiledDataCounter* _perfProfiledDataCounter;
};
Я использую C ++, чтобы использовать этот деструктор, когда объект выйдет из текущей области видимости.Идея состоит в том, чтобы создать PerfTimer в начале каждого метода Swizzled, и он позаботится об измерении истекшего времени для этого метода
PerfProfiledDataCounter - это простая структура, которая подсчитывает количество выполнения и все затраченное время (поэтому он может узнать, сколько времени в среднем уходит).
Кроме того, я создаю для каждого класса, который мне нужен профиль, категорию с именем "__Performance_Profiler_Category" и соответствует протоколу "__Performance_Profiler_Marker".Для облегчения создания я использую некоторые макросы, которые автоматически создают такие категории.Также у меня есть набор макросов, которые принимают имя селектора, тип возвращаемого значения и тип аргумента и создают селекторы для каждого имени селектора.
Для всех вышеперечисленных задач я создал набор макросов, чтобы помочь мне.Также у меня есть один файл с расширением .mm для регистрации всех классов и всех селекторов, которые я хотел бы профилировать.При запуске приложения я использую среду выполнения для извлечения всех классов, соответствующих протоколу "__Performance_Profiler_Marker" (то есть зарегистрированных), и поиска селекторов, помеченных для профилирования (эти селекторы начинаются с предопределенного префикса).Обратите внимание, что этот файл .mm является единственным файлом, для которого требуется расширение .mm, и нет необходимости изменять расширение файла для каждого класса, который я хочу профилировать.
После этого код превращает оригинальные селекторы в профилированные.В каждом профилированном я просто создаю PerfTimer и вызываю метод swizzled.
Вкратце, это моя идея, которая сработала довольно гладко.