概述
做一个流量监控,之前的代码是通过sysctl读取进程列表,取得kernel_task进程的启动时间作为系统启动时间,如果系统重启就需要把网卡记录的流量全部累加,否则用本次读取的网卡流量数据减去上一次记录的数据认为是这段时间内用户产生的流量。
在iOS9上 sysctl被封了,于是这段代码就挂了。没办法拿到系统启动时间,就会不停的累加网卡记录的全部流量。
使用sysctl取得kernel_task启动时间
+ (NSDate *)systemStartTime
{
size_t length = 0;
static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
int err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0);
if (err == -1)
{
err = errno;
}
if (err == 0)
{
struct kinfo_proc *procBuffer = (struct kinfo_proc *)malloc(length);
if(procBuffer == NULL)
{
return nil;
}
sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, procBuffer, &length, NULL, 0);
int count = (int)length / sizeof(struct kinfo_proc);
for (int i = 0; i < count; ++i)
{
NSString *procName = [NSString stringWithCString:procBuffer[i].kp_proc.p_comm encoding:NSUTF8StringEncoding];
if ([procName isEqualToString:@"kernel_task"])
{
return [NSDate dateWithTimeIntervalSince1970:procBuffer[i].kp_proc.p_un.__p_starttime.tv_sec];
}
}
}
return nil;
}
使用sysctlbyname取得boottime
+ (NSDate *)systemStartTime {
size_t size;
sysctlbyname("kern.boottime", NULL, &size, NULL, 0);
char *boot_time = malloc(size);
sysctlbyname("kern.boottime", boot_time, &size, NULL, 0);
uint32_t timestamp = 0;
memcpy(×tamp, boot_time, sizeof(uint32_t));
free(boot_time);
NSDate* bootTime = [NSDate dateWithTimeIntervalSince1970:timestamp];
NSLog(@"BootTime: %@", bootTime);
return bootTime;
}
boottime 也是有问题的,就是用户手动设置系统时间后,bootime会变动成手动设置的那个时刻;另外mach_absolute_time读取出来的tick数和bootime是一致的,个人猜测boottime其实就是换算mach_absolute_time()的结果。
最后
以上就是眼睛大皮皮虾为你收集整理的iOS 获取系统启动时间的全部内容,希望文章能够帮你解决iOS 获取系统启动时间所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复