美文网首页
开发问题笔记(四)

开发问题笔记(四)

作者: Kevin_wzx | 来源:发表于2019-02-25 18:04 被阅读0次

    目录

    1.上下文
    2.静态库与动态库的区别?
    3.如何高性能的给UIImageView加个圆角?
    4.一个tableView如何展示不同的业务数据?
    5.对于语句NSString *obj=[[NSData alloc]init]; obj在编译时和运行时分别是什么类型的对象?
    6.jsp有哪些内置对象?作用分别是什么?
    7.如何对ios设备进行性能测试?
    8.方法和选择器有何不同?
    9.iPhone5 的屏幕分辨率大小为 1136* 640 ?
    10.DAO模式
    11.类工厂方法
    12.c和obj-c如何混用?
    13.刷新
    14.自适应cell的手动代码定制
    15.TCP/IP和OSI对比?
    16.iOS 跳转到Appstore的链接及二维码
    17.Socket接口比较
    18.KVO详解
    19.去掉tableview顶端粘滞效果
    20.表格局部刷新时候选择的是None,还是有动画的解决方案
    21.封装的cell解决数据问题
    22.实现发票的选择效果
    23.在封装的cell中有添加BOOL值
    24.添加window
    25.在sourceTree上分支操作有误导致工程plist文件丢失,无法找回
    26.iOS程序执行顺序和controller的生命周期整理
    27.iOS- UITextField 输入框(控制输入小数点后两位)
    28.iOS框架了解
    29.iOS系统8.x上面icon图片花屏问题处理
    30.iOS开发中遇到BAD_ACCESS怎么办?

    1.上下文

    //
    //  CDAppContext.h
    //  day2016011901
    //
    //  Created by LUOHao on 16/1/19.
    //  Copyright (c) 2016年 mobiletrain. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    /**
     应用程序上下文
     */
    @interface CDAppContext : NSObject
    
    @property (nonatomic, readonly) NSURLSessionConfiguration *config;
    @property (nonatomic, copy) NSString *uid;
    
    + (instancetype) sharedContext;
    
    @end
    。m
    //
    //  CDAppContext.m
    //  day2016011901
    //
    //  Created by LUOHao on 16/1/19.
    //  Copyright (c) 2016年 mobiletrain. All rights reserved.
    //
    
    #import "CDAppContext.h"
    
    @implementation CDAppContext
    
    - (instancetype) init {
        @throw [NSException exceptionWithName:@"" reason:@"不能使用初始化方法创建单例对象" userInfo:nil];
    }
    
    - (instancetype) initPrivate {
        if (self = [super init]) {
            _config = [NSURLSessionConfiguration defaultSessionConfiguration];
            _config.timeoutIntervalForRequest = 15;
            _config.discretionary = YES;
        }
        return self;
    }
    
    + (instancetype)sharedContext {
        static CDAppContext *instance = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            if (!instance) {
                instance = [[self alloc] initPrivate];
            }
        });
        return instance;
    }
    
    @end
    
    

    2.静态库与动态库的区别?

    静态库和动态库是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。

    1.静态库好处
    i.模块化,分工合作,提高了代码的复用及核心技术的保密程度
    ii.避免少量改动经常导致大量的重复编译连接
    iii.也可以重用,注意不是共享使用

    2.动态库好处
    i.使用动态库,可以将最终可执行文件体积缩小,将整个应用程序分模块,团队合作,进行分工,影响比较小
    ii.使用动态库,多个应用程序共享内存中得同一份库文件,节省资源
    iii.使用动态库,可以不重新编译连接可执行程序的前提下,更新动态库文件达到更新应用程序的目的。
    iv.应用插件化
    v.软件版本实时模块升级
    vi.共享可执行文件 在其它大部分平台上,动态库都可以用于不同应用间共享,这就大大节省了内存。从目前来看,iOS仍然不允许进程间共享动态库,即iOS上的动态库只能是私有的,因为我们仍然不能将动态库文件放置在除了自身沙盒以外的其它任何地方。 不过iOS8上开放了App Extension功能,可以为一个应用创建插件,这样主app和插件之间共享动态库还是可行的。

    3.ios如何创建静动态库,查看链接:
    http://www.cocoachina.com/ios/20150921/13385.html

    3.如何高性能的给UIImageView加个圆角? (不准说 layer.cornerRadius)

    一般情况下给 UIImageView 或者说 UIKit 的控件添加圆角都是改变 clipsToBounds和 layer.cornerRadius, 这样大约两行代码就可以解决这个问题. 但是, 这样使用这样的方法会强制 Core Animation 提前渲染屏幕的离屏绘制, 而离屏绘制就会为性能带来负面影响.

    我们也可以使用另一种比较复杂的方式来为图片添加圆角, 这里就用到了贝塞尔曲线.

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; 
    imageView.center = CGPointMake(200, 300);
    UIImage *anotherImage = [UIImage imageNamed:@"image"]; 
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 1.0); 
    [[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:50] addClip];
    [anotherImage drawInRect:imageView.bounds];
    imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    [self.view addSubview:imageView];
    

    在这里使用了贝塞尔曲线"切割"个这个图片, 给 UIImageView
    添加了的圆角.

    4.一个tableView如何展示不同的业务数据?

    个人觉得要根据业务需求来,比如不同的业务数据但是其UI展示页面都差不多的情况下,可以通过修改数据源的形式,刷新tableView来实现其功能。如果UI展示页面完全不同,则可以根据type标记等等方式来自定义不同的cell来实现功能

    5.对于语句NSString *obj=[[NSData alloc]init]; obj在编译时和运行时分别是什么类型的对象?

    编译时是NSString类型;运行时是NSData类型

    6.jsp有哪些内置对象?作用分别是什么?

    JSP共有以下9种基本内置组件

    1、request对象 客户端请求,此请求会包含来自GET/POST请求的参数通过它才能了 解到客户的需求,然后做出响应。
    2、response对象 响应客户请求的有关信息
    3、session对象 它指的是客户端与服务器的一次会话,从客户端连到服务器的一个 WebApplication开始,直到客户端与服务 器断开连接为止。
    4、out对象 它是JspWriter类的实例,是向客户端输出内容常用的对象
    5、page对象 它是指向当前JSP页面本身,有点象类中的this指针,它是 java.lang.Object类的实例
    6、application对象 它实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭
    7、exception对象 它是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。
    8、pageContext对象 它提供了对JSP页面内所有的对象及名字空间的访问
    9、config对象 它是在一个Servlet初始化时,JSP引擎向它传递信息用的

    7.如何对ios设备进行性能测试?

    Profile-->Instruments-->Time Profiler

    8.方法和选择器有何不同?

    selector是一个方法的名字,method是一个组合体,包含了名字和实现.详情可以看apple文档。

    9.iPhone5 的屏幕分辨率大小为 1136* 640 ?

    答:屏幕分辨率:用于量度位图图像内数据量多少的一个参数。通常表示成ppi(每英寸像素Pixel per inch)。屏幕物理尺寸不变,分辨率越高,每单位面积内包含的细节(像素点)越多。

    10.DAO模式

    DAO(Data Access Object)模式实际上是两个模式的组合,即Data Accessor 模式和 Active Domain Object 模式,其中 Data Accessor 模式实现了数据访问和业务逻辑的分离,而Active Domain Object 模式,其中Data Accessor模式实现了数据访问和业务逻辑的分离,而Active Domain Object 模式实现了业务数据的对象化封装

    11.类工厂方法

    答:类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中,返回被创建的对象,并进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。工厂方法可能不仅仅为了方便使用。它们不但可以将分配和初始化合在一起,还可以为初始化过程提供对象的分配信息。类工厂方法的另一个目的是使类(比如NSWorkspace)提供单件实例。虽然init...方法可以确认一 个类在每次程序运行过程只存在一个实例,但它需要首先分配一个“生的”实例,然后还必须释放该实例。工厂方法则可以避免为可能没有用的对象盲目分配内存

    12.c和obj-c如何混用?

    1.obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj-c的代码,因为cpp只是cpp

    2.在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题

    3.在cpp中混用obj-c其实就是使用obj-c编写的模块是我们想要的。 如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。 如果模块以函数实现,那么头文件要按c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。

    • 总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,而不能直接使用实现代码,实际上cpp混用的是obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp.

    13.刷新

    创建完表格之后:
    一。
     MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
            [self loadDataModel:YES];
        }];
        [header setTitle:@"松开立即刷新数据" forState:MJRefreshStatePulling];
        [header setTitle:@"正在加载新的数据" forState:MJRefreshStateRefreshing];
        header.stateLabel.font = [UIFont defaultRegular];
        header.lastUpdatedTimeLabel.font = [UIFont defaultRegular];
        _tableView.header = header;
        [_tableView.header beginRefreshing];//
        
        MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
            [self loadDataModel:NO];
        }];
        footer.stateLabel.text = @"上拉或点击加载更多数据";
        footer.stateLabel.font = [UIFont defaultSeal];
        footer.automaticallyRefresh = NO;
        _tableView.footer = footer;
    
    二。
    - (void) loadDataModel:(BOOL) refresh {
        if (refresh) {
            _currentPage = kDefaultStartPage;
        }
        else {
            _currentPage += 1;
        }
        
        NSMutableDictionary *paramDict = [NSMutableDictionary dictionary];
        [paramDict setObject:@(_currentPage) forKey:@"page"];
        [paramDict setObject:@(kDefaultPageSize) forKey:@"number"];
        if (_categoryId && ![_categoryId isEqualToString:@"0"]) {
            [paramDict setObject:_categoryId forKey:@"cate_id"];
        }
        
        _manager = [AFHTTPSessionManager limitFreeManager];
        [_manager
            GET:_urlStr
            parameters:paramDict
            success:^(NSURLSessionDataTask *task, id responseObject) {
                if (!_dataArray) {
                    _dataArray = [NSMutableArray array];
                }
                else if (refresh) {
                    [_dataArray removeAllObjects];
                }
                
                for (NSDictionary *objDict in responseObject[@"applications"]) {
                    CDAppModel *model = [[CDAppModel alloc] init];
                    [model setValuesForKeysWithDictionary:objDict];
                    [_dataArray addObject:model];
                }
                
                [_tableView reloadData];
                [self endRefreshing];
            }
            failure:^(NSURLSessionDataTask *task, NSError *error) {
                NSLog(@"%@", error);
                _currentPage -= 1;
                [self endRefreshing];
            }
        ];
    }
    
    三。
    - (void) endRefreshing {
        if (_tableView.header.isRefreshing) {
            [_tableView.header endRefreshing];
        }
        
        if (_tableView.footer.isRefreshing) {
            [_tableView.footer endRefreshing];
        }
    }
    
    如何使用MJ刷新
    NSUInteger _currentPage;
    1.在建完表格视图后添加
    [self.view addSubview:_tableView];
        MJRefreshNormalHeader *hearder = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
            [self loadDataModel:YES];//加载数据
        }];
        [hearder setTitle:@"正在加载..." forState:MJRefreshStateRefreshing];
        _tableView.header = hearder;
        [hearder beginRefreshing];
        MJRefreshAutoNormalFooter *footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
            [self loadDataModel:NO];
        }];
        _tableView.footer = footer;
        footer.automaticallyRefresh = NO;
       
    2.加载数据
    - (void) loadDataModel:(BOOL) isRefresh {
        
        if (isRefresh) {
             _currentPage = kDefaultStartPage;
        }else {
            _currentPage += 1;
        }
         。。。。。。。。
        //此处写加载数据代码(把数组初始化放在success里面写
    if (!_dataArray) {
                  _dataArray = @[].mutableCopy;
              }
              else if (isRefresh){
                  [_dataArray removeAllObjects];
              } )
    
    }
    。。。。。。
    //刷新视图
              [_tableView reloadData];
              [self endRefresh];
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"%@",error);
            [self endRefresh];
            if (!isRefresh) {
                _currentPage -= 1;
            }
        }];
    
    
    3.- (void) endRefresh {
        [_tableView.header endRefreshing];
        [_tableView.footer endRefreshing];
    }
    

    14.自适应cell的手动代码定制

    屏幕快照 2016-04-29 上午11.17.11.png

    15.TCP/IP和OSI对比?

    屏幕快照 2018-02-09 下午2.39.21.png

    16.iOS 跳转到Appstore的链接及二维码

    https://www.jianshu.com/p/f84f05a5cc3c

    17.Socket接口比较

    屏幕快照 2018-02-09 下午2.39.50.png

    18.KVO详解

    http://www.jianshu.com/p/ed0422ffeeda
    KVO模型建立m文件中类似:

    屏幕快照 2018-03-13 上午11.39.05.png

    19.去掉tableview顶端粘滞效果

    屏幕快照 2018-03-19 上午11.43.13.png 屏幕快照 2018-03-09 上午10.48.29.png

    20.表格局部刷新时候选择的是None,还是有动画的解决方案

    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationNone];// 局部刷新
    
    - (void)viewDidLoad:(BOOL)animated {
        [super viewDidLoad];
        [UIView setAnimationsEnabled:NO];// 关掉
    }
    
    - (void)viewDidAppear:(BOOL)animated {// 不影响其他界面的动画使用(如封装的导航栏滑动效果界面间会影响)
        [super viewDidAppear:animated];
        [UIView setAnimationsEnabled:YES];
    }
    

    21.封装的cell解决数据问题

    1.在cell当中更新数据可以写一个暴露的方法reloadData(.h文件中),然后外部去调用这个方法(类似的有:表格1中嵌入一个表格2,表格2可以写在封装的view上面,然后暴露一个表格刷新的reloadData的方法,最后在表格1中调用它即可)

    2.也可以把数据更新方法直接放在重写模型的方法里面即可,外部不用管,直接映射模型就好

    22.实现发票的选择效果

    电子|纸质按钮控制收件信息cell的数量
    公司|个人按钮控制发票详情cell的数量
    方法:设置两个BOOL值来控制,在按钮的回调里设置该BOOL的状态,然后在其他要用到的地方直接利用该BOOL值判断即可

    电子发票公司类型 电子发票个人类型 纸质发票个人类型 屏幕快照 2018-03-19 下午3.10.26.png 屏幕快照 2018-03-19 下午3.09.08.png 屏幕快照 2018-03-19 下午3.09.59.png

    23.在封装的cell中有添加BOOL值

    要重写一下这个BOOL值就好比cell中绑定模型时重写模型,然后再用;
    如果想通过BOOL值来进行控件的不同布局,切记要在layoutSubviews方法里判断,不要直接写在初始化方法里判断,会有问题,初始化只走一次..

    24.添加window

    注意window在viewDidLoad里面创建是不会有的,详情查看控制的生命周期与之各个视图等关系;等视图加载完之后,例如在一个已加载的按钮的回调里创建是可以的

    25.在sourceTree上分支操作有误导致工程plist文件丢失,无法找回

    解决办法:切换到其他分支(切换不过去就提交要提交的东西,但不要推上去,目的只是为了切换);然后删除那个丢了文件的分支,删不掉就强制删除(远程的也删除);然后在同事的分支上新建一个最新的分支即可

    屏幕快照 2018-03-11 下午11.29.33.png
    WechatIMG80.jpeg

    26.iOS程序执行顺序和controller的生命周期整理

    https://www.jianshu.com/p/d60b388b19f5
    https://www.jianshu.com/p/a5f82922e387

    27.iOS- UITextField 输入框(控制输入小数点后两位)

    有很多做支付的时候,要求是输入控制在小数点后两位。我们只需要把对应的UITextField遵守代理,然后在代理方法中做下处理,具体效果图与代码如下

    效果图
    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
        
        NSMutableString *futureString = [NSMutableString stringWithString:textField.text];
        [futureString insertString:string atIndex:range.location];
        NSInteger flag = 0;
        const NSInteger limited = 2;// 这个可以自定义,保留到小数点后两位,后几位都可以
        
        for (NSInteger i = futureString.length - 1; i >= 0; i--) {
            
            if ([futureString characterAtIndex:i] == '.') {// 如果大于了限制的就提示
                if (flag > limited) {
                    
                    [SVProgressHUD showErrorWithStatus:@"输入金额请控制在小数点后两位" duration:2.0];
                    return NO;
                }
                break;
            }
            flag++;
        }
        return YES;
    }
    

    28.iOS框架了解

    http://ios.jobbole.com/84897/
    http://keeganlee.me/post/architecture/20160303
    http://keeganlee.me/post/architecture/20160214
    https://casatwy.com/iosying-yong-jia-gou-tan-kai-pian.html

    29.iOS系统8.x上面icon图片花屏问题处理

    这种情况下,把图片资源直接放在bundle下,不要放在image assets下

    图片.png

    https://www.jianshu.com/p/ca0bbb403143

    30.iOS开发中遇到BAD_ACCESS怎么办?

    https://www.jianshu.com/p/51188549ff06

    相关文章

      网友评论

          本文标题:开发问题笔记(四)

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