性能优化

程序性能优化:分为数据,UI,内存,程序响应速度四方面

数据方面:选择合适的数据存储方式 和避免数据的重复处理

选择合适的数据存储方式

小数据使用NSUserDefault存储;

机密数据存储在服务器或者keychain;

大量数据使用sqlite或者coreDate或者本地文件存储

避免数据的重复处理

把处理好的数据使用字典保存,下次使用时直接获取即可

UI方面

1.优化tableView

2.正确使用背景图片

3.避免庞大的xib

如果必须使用xib,可以考虑storyboard,因为storyboard只在需要时实例化它的viewcontroller

4.合理使用视图的复用标记

对于tableview/UICollection的cell/head/foot 等都可以添加复用标记,来避免多次创建

内存方面

1.使用ARC管理内存

2.尽量处理内存警告

3.在数据量比较大的地方主动使用autoreleasepool

4.属性使用懒加载:懒加载一来是只创建一次,二来避免一次性全部创建导致的内存不足

5.合理使用缓存,包括图片缓存,大的scrollview的页面缓存

程序响应速度

1.尽量缩短app的启动时间,只在app启动的主线程做一些必要的设置和页面加载,其他的都放到子线程中进行

2.主线程只做跟UI相关的事情,大量任务或者大量数据处理(比如图片下载,文件访问)等耗时操作等需要在子线程中异步执行)

如何优化tableview

  • 正确使用cell复用;

  • cell赋值和计算cell高度分开,并缓存高度到数据源中;

  • 按需加载。

    按需加载就是滚动过程中不加载cell,在松开手指时。根据indexpathForVisiblerows 获取到所有可视cell索引,根据cellForRowAtIndexPath方法获取到具体的可视cell并进行加载
    
    滚动时,松开手指的时候scroll会回调delegate方法scrollViewWillEndDragging。在这里可以按需加载
    
    停止滚动时:scrollViewDidEndDecelerating可以加载需要显示的cell图片
    
  • 减少subview个数,复杂图层使用coreText,coreGraphic绘制在一个图层上

  • 尽量少用或者不用透明图层

  • 如果cell内部的内容来时web。需使用异步加载,并缓存请求结果。

  • 图片尺寸提前处理好。图片如果没有根据需要提前裁剪,压缩,拉伸处理好,不要在cell加载时就使用contentMode.因为contentMode需要每次对压缩图片做变化矩阵,会影响滚动

如何正确使用背景图片

  • 纯色背景使用backgroundcolor,

  • 有规律的小格子则使用UIColor的ColorWithPatterImage来处理

  • 其他使用addSubview添加一个UIImageView的背景图片

tableView滚动时不下载图片如何实现?

方式1:使用tableview的delegate实现

1.数据模型中增加参数isload代表图片是否已下载,NO是未下载,YES是已下载。在cellforrow方法中如果对应的数据模型中的isload为NO则设置为默认图片

2.scrollViewDidEndDragging:decelerate 为NO时表示停止拖拽,此时开始加载需要显示的cell图片

3.scrollViewDidEndDecelerating停止滚动,此时可以加载需要显示的cell图片 参考网址:https://www.jianshu.com/p/633fce8a6d98)

方式2:使用runloop实现,将图片加载的方法的runloop设置为DefalutRunloopMode。因为滚动时是trackingRunLoopModel不会加载图片

假如MVC的Controller太臃肿,如何优化?

1.将网络请求抽取到单独的类中

  • 2.在基类中处理公共逻辑

  • 3.将页面分段处理,使整个viewcon由多个UIView的子类组合而成,然后controller只负责事件管理即可

  • 4.使用MVVM模式.给view构建viewModel

ios 使用AFNetwork上传图片

多张和单张的通用方法如下

与单张图片上传相比只是把data从一个LYUPImageDataParamModel对象变为 LYUPImageDataParamModel对象的数组即可

//上传多张图片(LYUPImageDataParamModel)
- (void)URLSessionUploadFileArray:(NSString *)URLString
              parameters:(id)parameters
       array:( NSArray*)dataArray
                 success:(void (^)(id))success
{
    NSMutableString *urlStr = [NSMutableString stringWithString:[LYCommonFunction getStringValueForKey:LYCurrentServiceURL]];
    [urlStr appendString:URLString];

    AFHTTPSessionManager*   imageManager = [AFHTTPSessionManager manager];
    imageManager.requestSerializer = [ AFHTTPRequestSerializer serializer ];
    imageManager.responseSerializer = [ AFHTTPResponseSerializer serializer ];

    [imageManager POST:urlStr
            parameters:parameters
constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
    //这个就是参数
    for (int i = 0; i< dataArray.count; i++) {
        LYUPImageDataParamModel *dataModel = dataArray[i];
        [formData appendPartWithFileData:dataModel.data
                                    name:dataModel.name
                                fileName: dataModel.fileName
                                mimeType:dataModel.mimeType];

    }

} progress:^(NSProgress * _Nonnull uploadProgress) {


} success:^(NSURLSessionDataTask *  task, NSData   *responseDic) {
    NSDictionary * data = [NSJSONSerialization JSONObjectWithData:responseDic options:0 error:0];
    NSLog(@"ddd%@",data);
    success(data);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

    success(@{@"msg":@"请求失败"});


}];

}

4.设置状态栏背景色

UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
    if ([statusBar respondsToSelector:@selector(setBackgroundColor:)])
    {
        statusBar.backgroundColor = [UIColor clearColor];
    }

添加到appdelegate的didFinished方法中即可控制所有的页面状态栏背景色

5.设置状态栏的字色

  1. 修改plist文件

在info plist里面将View controller-based status bar appearance设置成NO

2.修改viewWillAppear

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; 
//导航白色文字

黑色文字是UIStatusBarStyleDefault,而且只能是白色或者黑色

6.部分页面支持横竖屏

1.Xcode的Capabilities的Device Orientation选择横屏和竖屏

2.全局页面是竖屏,

在跟视图控制器NavigaitonController中实现横竖屏切换的代理方法,代码如下

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait ||

            interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown );
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return  UIInterfaceOrientationMaskPortrait;
}
//意思是只支持竖屏

3.在需要横屏的视图控制器也实现横竖屏切换的代理方法,并修改为viewcontroller需要的是横屏,代码如下

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||

            interfaceOrientation == UIInterfaceOrientationLandscapeRight );
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return  UIInterfaceOrientationMaskLandscape;
}

是iphone同时高度大于plus的高度(736)才采用83的tabbar高度

#define LYTabbarH ((LYHIGHT>736 && [[LYCommonFunction IphoneDeviceName]isEqualToString:@"iphone"])?83:49)

//页面起点

#define LYViewTopY
(LYNavigationBarH+LYWINDOW_TOP_Y)

####4.页面底部预留的安全位置
所有页面均预留地下的高度

#define LYViewBootomY (LYTabbarH-49)

JSRUN前端笔记, 是针对前端工程师开放的一个笔记分享平台,是前端工程师记录重点、分享经验的一个笔记本。JSRUN前端采用的 MarkDown 语法 (极客专用语法), 这里属于IT工程师。