• iOS开发-Instruments性能调优


    性能是苹果审核的一个很重要的部分,CPU,内存,图形绘制,存储空间和网络性能都是应用的重要的评估和组成部分。不管是作为个人应用开发者还是企业的开发人员,都需要遵循的一个原则是站在用户的角度去思考问题,比如说常见的适配问题,不能因为不同的机型导致最终出现的UI效果差异很大,用户在使用的过程的中最好不要表现出明显的卡顿现象,或者更严重的是出现App闪退,出现闪退的结果就是应用被删,这是属于比较严重的问题。Instruments是目前最强大的性能调试工具之一,有助于我们解决应用存在的性能问题。Instruments是里面包括了内存管理工作,I/O以及网络过去,本文主要讲述的是Allocation和Time Profle。

    Allocations(内存分配)

    调试之前,我们先来看一个效果图:

    就是动态的将文字输出在视图上,下面贴出代码你会发现开始还好运行到慢的简直跟蜗牛有的一拼,不要运行太久,否则内存不够用,代码如下:

    @implementation FETextView
    
    - (id)initWithFrame:(CGRect)frame text:(NSString *)text {
        self = [super initWithFrame:frame];
        if (self) {
            [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(appendNextCharacter) userInfo:nil repeats:YES];
            _text = [text copy];
            self.backgroundColor = [UIColor whiteColor];
        }
        return self;
    }
    //原文地址:http://www.cnblogs.com/xiaofeixiang
    - (void)appendNextCharacter {
        for (NSUInteger i = 0; i <= self.index; i++) {
            if (i < self.text.length) {
                UILabel *label = [[UILabel alloc] init];
                label.text = [self.text substringWithRange:NSMakeRange(i,1)];
                label.opaque = NO;
                [label sizeToFit];
                CGRect frame = label.frame;
                frame.origin = [self originAtIndex:i
                                          fontSize:label.font.pointSize];
                label.frame=frame;
                [self addSubview:label];
            }
        }
        self.index++;
    }
    
    - (CGPoint)originAtIndex:(NSUInteger)index
                    fontSize:(CGFloat)fontSize {
        if (index == 0) {
            return CGPointZero;
        }
        else {
            CGPoint origin = [self originAtIndex:index-1 fontSize:fontSize];
            NSString *
            prevCharacter = [self.text
                             substringWithRange:NSMakeRange(index-1,1)];
            CGSize
            prevCharacterSize = [prevCharacter
                                 sizeWithAttributes:@{ NSFontAttributeName:
                                                           [UIFont systemFontOfSize:fontSize]
                                                       }];
            origin.x += prevCharacterSize.width;
            if (origin.x > CGRectGetWidth(self.bounds)) {
                origin.x = 0;
                origin.y += prevCharacterSize.height;
            }
            return origin;
        }
    }
    @end
    

    主视图控制器的调用代码:

        NSString *
        path = [[NSBundle mainBundle] pathForResource:@"FlyElephant"
                                               ofType:@"txt"];
        
        FETextView *textView = [[FETextView alloc]
                               initWithFrame:CGRectMake(0, 64, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds))
                               text:[NSString stringWithContentsOfFile:path
                                                              encoding:NSUTF8StringEncoding
                                                                 error:nil]];
        [self.view addSubview:textView];
    

    这个时候我们通过Allocation可以进行内存分析,将Xcode切换为Release状态,通过Product→Profile(Cmd+i)找到Allocations:

     1.红色的按钮是表示停止和启动应用程序,不要理解成了暂停,Objective-C所有的对象都是在堆上分配的,记得勾选一下All Heap  Allocations:

    2.点击All  Heap  Allocation,勾选Call  Tree,同时不查看系统的函数库:

    3.具体方法占用的内存,可以逐级点开,效果如下:

    以上是常规的Allocations使用,关于第二张图的有框中的几个选项可以解释一下:

    Separate by Thread: 每个线程应该分开考虑,考虑到应用程序中GCD的存在;
    Invert Call Tree: 从上倒下跟踪堆栈,这意味着你看到的表中的方法,将已从第0帧开始取样,利用栈的先进后出的特性,我们可以在栈顶看到最近调用的函数;
    Hide System Libraries: 勾选此项会显示app的代码,这是非常有用的;
    Flatten Recursion: 递归函数, 每个堆栈跟踪一个条目;

    Time Profiler

    Time Profiler在Allocations的下方,如图所示:

    1.Allocations可以更好查看占用的内存,Time Profiler可以更好查看时间:

    2.点击消耗时间最多的originAtIndex方法,效果如下:

    3.查看具体每一行代码的占用时间的百分比,点击Xcode的图标可以进入Xcode中查看代码:

     

    关于Time  Profiler的基本用户大概就是这样,关于开发我们还有可能使用到Leak内存泄露工具,基本方法大同小异,关于内存泄露包括两种泄漏:

    第一种内存泄漏是指生成的实例对象用完之后不被释放,就会造成内存无法被重新使用;

    第二种内存泄漏是发生在内存继续分配形成循环引用,并永远不会有机会被释放;
  • 相关阅读:
    v4l2程序实例
    uboot的readme导读
    基于Linux的v4l2视频架构驱动编写
    V4L2
    Uboot优美代码赏析1:目录结构和malkefile分析
    查找 mysql 配置文件 my.cnf
    thinkphp中array_diff运行无效 Invalid opcode 153/1/8
    thinkphp后端开发ajax接口开发测试
    Thinkphp getLastSql函数用法
    web日志分析的重要性
  • 原文地址:https://www.cnblogs.com/xiaofeixiang/p/4727557.html
Copyright © 2020-2023  润新知