part2

作者: SSJeremy | 来源:发表于2018-08-31 17:23 被阅读9次

    1.性能优化相关
    instruments的使用
    dSYM内存地址解析 对象啥名字
    图像性能
    减少view个数
    减少使用opacity,半透明效果,或者不要把半透明加载一个变化的view上,因为不仅底层要更新,半透明效果也要更新。

    栅格化restresize == true; cache它的layer bitmap那个图 下次就不用重绘了
    offscreen-rendered离屏渲染

    autolayout和绝对布局性能的插笔鹅仔view小于400subview基本忽略不计
    轻量化住线程:图片预加载、coretext
    性能优化重点:缓存 一般动画会消耗gpu(CoreAnimation OpenGL)多点cpu(CGGraghic)

    imageNamed主线程占用挺高的
    滑动30针就问题不大了 否则就要优化了

    uikit的坐标系和CGContext是不一样的 一个原点在左上角 一个原点在左下角,所以就涉及到坐标转换。 矩阵变换。
    一个文字是CTRun baseline 上部asent下部decent
    缓存 空间换时间
    性能优化 减少住线程任务 预加载
    tableview享元模式
    while(condition){
    ......
    condition = 0;
    }
    线程交给runloop去做

    SDWebImage 同一地址内容改变了 可以用图片md5加密做key。
    imageNamed会自动给你cache 内存会升的比较快
    autoreleasepool 延迟释放MRC retainCount == 0但没释放
    系统的autor
    runloop会创建一个 main函数的主runloop会创建一个 touch event时间循环 线程 结束的时候会销毁

    文本太大 分段加载 类似tableview 线程 有线程栈 有大小 2m的话 内存/2就是最多创建的线程数
    xib有磁盘加载到内存的过程 所以纯代码性能会比较好
    内存的速度是磁盘的100倍+

    2.下拉上拉刷新
    //当你被添加到superView的时候或者从superView上移除的时候,都会调用willMoveToSuperview方法 (添加参数有值 移除没有)

    • (void)willMoveToSuperview:(UIView *)newSuperview

    if (self.scrollView.dragging) { //正在拖动的过程中

    //注意:获取bundle里的图片方法
            _arrowImageView =
            [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:[[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"MJRefresh" ofType:@"bundle"]] pathForResource:@"arrow@2x" ofType:@"png"]]];
            _arrowImageView.tintColor = self.descriptionLable.textColor;
    
    - (void)setPullingPercent:(CGFloat)pullingPercent {
        
        [super setPullingPercent:pullingPercent];
        
        NSArray *images = self.stateImages[@(EOCRefreshStateIdle)];
        if (self.state != EOCRefreshStateIdle || images.count == 0) return;
        // 停止动画
        [self.gifImageView stopAnimating];
        // 设置当前需要显示的图片
        NSUInteger index =  images.count * pullingPercent;
        if (index >= images.count) index = images.count - 1;
        self.gifImageView.image = images[index];
        
    }
    
    - (void)setState:(EOCRefreshState)state {
        
        [super setState:state];
        
        if (state == EOCRefreshStateRefreshing || state == EOCRefreshStatePulling) {
            
            _gifImageView.animationImages = _stateImages[@(EOCRefreshStateRefreshing)];
            _gifImageView.animationDuration = [_stateAnimationDurations[@(EOCRefreshStateRefreshing)] doubleValue];
            [_gifImageView startAnimating];
            
        } else if (state == EOCRefreshStateIdle) {
            
            [_gifImageView stopAnimating];
            
        }
        
    }
    

    0.框架要考虑三点
    1.分层结构
    2。可用性-》分类 初始化的实现-〉每一个方法
    3.baseview:prepare方法(做准备工作) ->placeSubviews(修改子view的布局)-> viewWillMoveToSuperView来设置kvo之类的->kvo的监听方法(根据偏移量设置状态)->根据不同状态进行操作
    上次刷新时间用NSUserdefault可以存 上次结束的时候存入(会造成多个tableview之间时间的混乱)
    每个像素4个字节 动画用图片数组实现

    backFooter AutoFooter
    contentSize viewDidLoad里面不行 viewDidAppear里面可以 因为tableview的contentSize要数据都弄出来才确定

    contentSize不准确 可以监听 一改变就重新赋值

    self.originalInsets = self.scrollView.eoc_inset;  //经验之谈:如果是你自己手动设置的contentInset,那么设置好了,立马就能够或得到这个值;如果是系统来给你提供的,比如naviagationController和scrollView结合导致的偏移,这个contentInset,就需要选择时机来获得了
     ///iOS 11 scrollView的contentInset
    //adjustContentInsets = contentInset + safeAreaContentInsets 
    
    - (UIEdgeInsets)eoc_inset {
        
        UIEdgeInsets insets = self.contentInset;
        
        if (@available(iOS 11, *)) {
            
            insets = self.adjustedContentInset;
            
        }
        
        return insets;
        
    }
    
    - (void)setEoc_insetT:(CGFloat)eoc_insetT
    {
        //右边是不是等于adjustContentInsets:safeAreaInset+contentInset
        
        UIEdgeInsets inset = self.contentInset;
        inset.top = eoc_insetT;
        
        if (@available(iOS 11, *)) {
            
            inset.top -= self.safeAreaInsets.top;
            
        }
        
        self.contentInset = inset;
        
    }
    self.view
    self.window为nil说明还没有添加到界面上来 还没有添加进去
    viewDidLoad里面view还没有添加到window上面self.view.superView == nil
    
    

    2.本地数据储存
    1.沙盒
    2.bundle
    3.归档KeyedArchiver
    4.keychain

    -->沙盒

    NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSLog(@"%@", filePath);
    

    documents {

    大文件尽量不要存储在这个目录下(视频文件)如果不做任何处理,审核,检查出来,就被拒,
    如果不想被拒 1 文件非备份操作设置  2 大文件转移目录
    默认是备份的
    

    }

    #import <sys/xattr.h>
    
    //非备份操作
    - (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL*)URL
    {
        const char* filePath = [[URL path] fileSystemRepresentation];
        const char* attrName = "com.apple.MobileBackup";
        u_int8_t attrValue = 1;
        
        int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);
        return result == 0;
    }
    
    

    Library {
    Caches 缓存 非备份
    Preferences(默认是备份)(plist文件 NSUserDefaults)

    }
    默认的网络请求是有缓存的 保存在cache里

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        
        [[NSUserDefaults standardUserDefaults] setObject:@"3" forKey:@"tow"];
        [[NSUserDefaults standardUserDefaults] synchronize];//提交 防止文件还没写进去就有地方开始读了无数据
        
    }
    

    tmp(临时)
    // app功能 清除缓存的功能 (1系统的文件, 2 自己创建)

    大文件可以存放在document下并设置非备份 或者放在libraray的cache或者自己创一个

    =======
    boundle 资源, 不参与编译
    黄色/蓝色(蓝色资源文件夹,不参与编译)

    ======

    获取bundle内的图片
     _imageView.image = [UIImage imageNamed:@"EOCBundle.bundle/11.png"];
    
    
        // 用代码取路径
        
        NSString *boudlePath = [[NSBundle mainBundle] pathForResource:@"EOCBundle" ofType:@"bundle"];
        
        NSBundle *eocBoundle = [NSBundle bundleWithPath:boudlePath];
        
        NSString *imagePath = [eocBoundle pathForResource:@"11" ofType:@"png"];
        
        _imageView.image = [UIImage imageWithContentsOfFile:imagePath];
    

    归档 遵循NSCoding协议。 加密解密

    //归档 类似于编码
    - (void)encodeWithCoder:(NSCoder *)aCoder{
        
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeObject:self.age forKey:@"age"];
        
    }
    
    //解 读出来 生成一个对象
    - (instancetype)initWithCoder:(NSCoder *)aDecoder{
        
        EOCClass *eocClass = [EOCClass new];
        eocClass.name = [aDecoder decodeObjectForKey:@"name"];
        eocClass.age = [aDecoder decodeObjectForKey:@"age"];
        return eocClass;
    }
    
    - (void)saveObject{
        
        EOCClass *eocClass = [EOCClass new];
        eocClass.name  = @"eocClass";
        eocClass.age = @"11";
        //
        
        NSData *eocData = [NSKeyedArchiver archivedDataWithRootObject:eocClass];
        NSLog(@"data数据::%s", [eocData bytes]);
        
        NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        filePath = [filePath stringByAppendingPathComponent:@"eocClass"];
        [eocData writeToFile:filePath atomically:YES];
        
    }
    
    
    - (void)getObject{
        
        NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        filePath = [filePath stringByAppendingPathComponent:@"eocClass"];
        
        EOCClass *eocClass = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
        
        NSLog(@"%@, %@", eocClass.name, eocClass.age);
        
        EOCClass *eocClassTwo = [eocClass copy];
        
    }
    
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        
        [self getObject];
    }
    
    对象要考呗的话需要实现NSCopying协议
    //// copy
    - (id)copyWithZone:(nullable NSZone *)zone{
        
        EOCClass *eocClass = [EOCClass new];
        
        eocClass.name = self.name;
        eocClass.age = self.age;
        
        return eocClass;
        
    }
    
    

    相关文章

      网友评论

          本文标题:part2

          本文链接:https://www.haomeiwen.com/subject/rgfziftx.html