DTrace可以做到这一点,但只能在iPhone模拟器中实现(它得到了雪豹的支持,但还没有得到iOS的支持)。我在MacResearch上有两篇关于这项技术的报道
here
和
here
在这里,我将介绍一些使用dtrace查找特定方法以及何时调用这些方法的案例研究。
例如,我创建了以下dtrace脚本来测量在具有cp前缀的类上调用方法的次数,以及这些方法中花费的总时间:
#pragma D option quiet
#pragma D option aggsortrev
dtrace:::BEGIN
{
printf("Sampling Core Plot methods ... Hit Ctrl-C to end.\n");
starttime = timestamp;
}
objc$target:CP*::entry
{
starttimeformethod[probemod,probefunc] = timestamp;
methodhasenteredatleastonce[probemod,probefunc] = 1;
}
objc$target:CP*::return
/methodhasenteredatleastonce[probemod,probefunc] == 1/
{
this->executiontime = (timestamp - starttimeformethod[probemod,probefunc]) / 1000;
@overallexecutions[probemod,probefunc] = count();
@overallexecutiontime[probemod,probefunc] = sum(this->executiontime);
@averageexecutiontime[probemod,probefunc] = avg(this->executiontime);
}
dtrace:::END
{
milliseconds = (timestamp - starttime) / 1000000;
normalize(@overallexecutiontime, 1000);
printf("Ran for %u ms\n", milliseconds);
printf("%30s %30s %20s %20s %20s\n", "Class", "Method", "Total CPU time (ms)", "Executions", "Average CPU time (us)");
printa("%30s %30s %20@u %20@u %20@u\n", @overallexecutiontime, @overallexecutions, @averageexecutiontime);
}
这将生成以下格式良好的输出:
Class Method Total CPU time (ms) Executions Average CPU time (us)
CPLayer -drawInContext: 6995 352 19874
CPPlot -drawInContext: 5312 88 60374
CPScatterPlot -renderAsVectorInContext: 4332 44 98455
CPXYPlotSpace -viewPointForPlotPoint: 3208 4576 701
CPAxis -layoutSublayers 2050 44 46595
CPXYPlotSpace -viewCoordinateForViewLength:linearPlotRange:plotCoordinateValue: 1870 9152
...
虽然您可以从命令行创建和运行dtrace脚本,但最好的办法可能是在instruments中创建一个自定义的instrument,并在该instrument中填充适当的d代码。然后您可以在模拟器中针对您的应用程序轻松地运行它。
同样,这在设备上不起作用,但是如果您只想统计某个对象被调用的次数,而不是它运行的持续时间,那么这可能会起作用。