美文网首页
iOS面试题

iOS面试题

作者: 阿凡提说AI | 来源:发表于2017-11-06 23:01 被阅读27次

    1.MVC、MVP、MVVM的区别?
    MVC:

    View上面显示什么东西,取决于Model。
    只要Model数据改了,View的显示状态也会跟着更改。
    Controller负责初始化Model,并将Model传递给View去解析展示。
    

    MVVM:

    M:模型,负责数据的存储。
    V:View和ViewController
    VM:ViewModel,专门负责数据请求、业务逻辑等业务。
    

    MVP:

    M、V与上相同。
    Presenter:作为model和view的中间人,从model层获取数据之后传给View,使得View和model有更强的复用性。
    

    2.自动布局有哪些?
    (1)Autolayout
    1)约束和参照
    2)代码实现
    要先禁止autoresizing功能,设置view的下面属性为NO.

    view.translatesAutoresizingMaskIntoConstraints = NO;
    // 添加高度约束
    NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:buleView relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:40];
    

    自动布局核心计算公式
    obj1.property1 = (obj2.property2*multiplier)+constant value
    3)VFL语言

    H:[cancelButton(72)] - 12 - [acceptButton(50)]
    H:[wideView(>=60@700)]
    V:[redBox][yellowBox(==redBox)]
    

    (2)Masonry:
    约束的类型:
    1.尺寸:width\height\size
    2.边界:left\leading\right\trailing\top\bottom
    3.中心点:center\centerX\centerY
    4.边界:edges

    [blueView mas_makeConstraints:^(MASConstarintMake *make){
          // 宽度约束
          make.width.equalTo(@100);
          // 宽度约束
          make.height.equalTo(@100);
          // 右边
          make.right.equalTo(self.view.mas_right).offset(-20);
          // 顶部
          make.top.equalTo(self.view.mas_top).offset(20);
    }
    
    // 这个方法会将以前的所有约束删除,添加新的约束
    [blueView mas_remakeConstraints^(MASConstraintMaker *make){
            
    }
    
    // 这个方法将会覆盖以前的某些特定的约束
    [blueView mas_updateConstraints^(MASConstraintMaker *make){
            
    }
    

    (3)SDAutolayout

    _view.sd_layout.leftSpaceToView(self.view,10).topSpaceToView(self.view,80),heightIs(130).widthRatioToView(self.view,0.4);
    _label.sd_layout.autoHeightRadio(0);
    

    tableView高度自适应设置3步:
    1)cell布局设置之后调用以下方法就可以实现高度自适应(注意:如果用高度自适应则不要再以cell的底边去参考布局其子view)

    [cell setupAutoHeightWithBottomView:_view4 bottomMargin:10];
    

    2)获取自动计算出cell的高度

    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
          id model = self.modelsArray[indexPath.row];
          // 获取cell高度
          return [self.tableView cellHeightForIndexPath:indexPath model:model  keyPath:@"model"  cellClass:[DemoVC9Cell class] contentViewWidth:cellContentViewWidth];
    
    }
    

    3.切换分支

    git checkout -b branch1 origin/branch1
    

    4.递归函数
    (1)必须有一个明确的结束标志
    (2)自己调用自己

    // 设置一个函数用来计算B的n次方
    
    int myPow2(int base,int n)
    {
          int result = 1;
          if(n<0){
                //结束标志
                return result;
          }else{
              return myPow2(base,n-1)*base;
         }
    
    }
    

    5.代码冲突解决方法
    (1)代码文件冲突
    当代码文件冲突时,是可以打开xcode的,然后逐个解决就行。

    <<<<<<<<<<<<HEAD
    ================
    >>>>>>>>>>>>masterDv
    

    <<<<<<<<<<<<HEAD与================之间是本地的代码。
    ================与>>>>>>>>>>>>masterDv之间是对方的代码
    根据情况来删除
    (2)配置文件冲突
    当配置文件冲突时,打不开xcode,这时需要进行项目文件夹xxx.xcodeproj打开project.pbxproj,然后逐个解决即可。
    6.九宫格的思路
    核心点就是算x,y。控制在第index/cols行,第index%cols列。(cols列数)。

    // 每一列之间的间距
    CGFloat colMargin = (self.shopView.frame.size.width - cols*shopW)/(cols - 1);
    // 每一行的间距
    CGFloat rowMargin = 10;
    X值:NSUInterger col = index%cols;
    CGFloat shopX = col*(shopW +colMargin);
    Y值:NSUInteger row = index/cols;
    CGFloat shopY = row*(shopH +rowHeight);
    

    7.通知、代理、block
    (1)发通知

    // 发通知
    NSDictionary *dic = [NSDictionary dictionaryWithObject:@"userInfo消息" forKey:@"param"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"noti3"  object:nil userInfo:dic];
    
    // 监听
    [[NSNotificationCenter defaultCenter] addObserver:self selector:(noti3:) name:@"noti3" object:nil];
    // 调用方法
    - (void)noti3:(NSNotification *)noti
    {
            //使用userInfo处理消息
            NSDictionary *dic = [noti userInfo];
            NSString *info = [dic objectForKey:@"param"];
    }
    

    最后,记得在发送通知消息的页面,在dealloc方法里面移除观察者。

    -(void)dealloc{
          [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    

    (2)代理设计模式的开发步骤
    1)拟一份协议(协议名字的格式:控制名+Delegate),在协议里面生命一些代理方法。(一般代理方法都是@optional)
    2)声明一个代理属性

    @property(nonatomic,weak)id<代理协议>delegate;
    

    3)在内部发生某种行为时,调用代理对应的代理方法,通知代理发生什么事。
    4)设置代理:xxx.delegate = yyy;
    5)yyy对象准守协议,实现代理方法。
    (3)block逆向传值
    A文件(用来保存block代码)

    addVc.block = ^(Contact *contact){
              //1.联系人添加到数组
              [self.contacts addObject:contact];
              //2.刷新表格
              [self.tableView reloadData];
    }
    

    B文件:(逆传)
    .h文件

    typedef void(^AddViewControllerBlock)(Contact *contact);
    @property(nonatomic,strong)AddViewControllerBlock block;
    

    .m文件

    //0.把文本框的值包装包装成模型人模型
    Contact *c = [Contact contactWithName:_nameField.text phone:_phoneField.text];
    
    // 1.把联系人添加到联系人控制器的数组,让联系人刷新表格
    if(_block){
      _block(c);
    }
    
    // 2.回到联系人控制器
    [self.navigationController popViewControllerAnimated:YES];
    

    8.支付的过程
    (1)首先从自己的服务器获取商品列表
    (2)通过商品数据请求生成订单接口。
    (3)根据生成订单接口返回的数据,调用ping++的api
    (4) 在支付宝或微信进行支付
    (5)API调用成功之后再通过服务器返回的数据判断交易状态。
    9.瀑布流
    XMGWaterflowLayout.h

    #import <UIKit/UIKit.h>
    
    @interface XMGWaterflowLayout : UICollectionViewLayout
    
    @end
    

    XMGWaterflowLayout.m

    #import "XMGWaterflowLayout.h"
    
    /** 默认的列数 */
    static const NSInteger XMGDefaultColumnCount = 3;
    /** 每一列之间的间距 */
    static const CGFloat XMGDefaultColumnMargin = 10;
    /** 每一行之间的间距 */
    static const CGFloat XMGDefaultRowMargin = 10;
    /** 边缘间距 */
    static const UIEdgeInsets XMGDefaultEdgeInsets = {10, 10, 10, 10};
    
    @interface XMGWaterflowLayout()
    /** 存放所有cell的布局属性 */
    @property (nonatomic, strong) NSMutableArray *attrsArray;
    /** 存放所有列的当前高度 */
    @property (nonatomic, strong) NSMutableArray *columnHeights;
    @end
    
    @implementation XMGWaterflowLayout
    
    - (NSMutableArray *)columnHeights
    {
        if (!_columnHeights) {
            _columnHeights = [NSMutableArray array];
        }
        return _columnHeights;
    }
    
    - (NSMutableArray *)attrsArray
    {
        if (!_attrsArray) {
            _attrsArray = [NSMutableArray array];
        }
        return _attrsArray;
    }
    
    /**
     * 初始化
     */
    - (void)prepareLayout
    {
        [super prepareLayout];
    
        // 清除以前计算的所有高度
        [self.columnHeights removeAllObjects];
        for (NSInteger i = 0; i < XMGDefaultColumnCount; i++) {
            [self.columnHeights addObject:@(XMGDefaultEdgeInsets.top)];
        }
    
        // 清除之前所有的布局属性
        [self.attrsArray removeAllObjects];
        // 开始创建每一个cell对应的布局属性
        NSInteger count = [self.collectionView numberOfItemsInSection:0];
        for (NSInteger i = 0; i < count; i++) {
            // 创建位置
            NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
            // 获取indexPath位置cell对应的布局属性
            UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
            [self.attrsArray addObject:attrs];
        }
    }
    
    /**
     * 决定cell的排布
     */
    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        return self.attrsArray;
    }
    
    /**
     * 返回indexPath位置cell对应的布局属性
     */
    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        // 创建布局属性
        UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
        // collectionView的宽度
        CGFloat collectionViewW = self.collectionView.frame.size.width;
    
        // 设置布局属性的frame
        CGFloat w = (collectionViewW - XMGDefaultEdgeInsets.left - XMGDefaultEdgeInsets.right - (XMGDefaultColumnCount - 1) * XMGDefaultColumnMargin) / XMGDefaultColumnCount;
        CGFloat h = 50 + arc4random_uniform(100);
    
        // 找出高度最短的那一列
    //    __block NSInteger destColumn = 0;
    //    __block CGFloat minColumnHeight = MAXFLOAT;
    //    [self.columnHeights enumerateObjectsUsingBlock:^(NSNumber *columnHeightNumber, NSUInteger idx, BOOL *stop) {
    //        CGFloat columnHeight = columnHeightNumber.doubleValue;
    //        if (minColumnHeight > columnHeight) {
    //            minColumnHeight = columnHeight;
    //            destColumn = idx;
    //        }
        //    }];
    
        // 找出高度最短的那一列
        NSInteger destColumn = 0;
        CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
        for (NSInteger i = 1; i < XMGDefaultColumnCount; i++) {
            // 取得第i列的高度
            CGFloat columnHeight = [self.columnHeights[i] doubleValue];
    
            if (minColumnHeight > columnHeight) {
                minColumnHeight = columnHeight;
                destColumn = i;
            }
        }
    
        CGFloat x = XMGDefaultEdgeInsets.left + destColumn * (w + XMGDefaultColumnMargin);
        CGFloat y = minColumnHeight;
        if (y != XMGDefaultEdgeInsets.top) {
            y += XMGDefaultRowMargin;
        }
        attrs.frame = CGRectMake(x, y, w, h);
    
        // 更新最短那列的高度
        self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
    
        return attrs;
    }
    
    - (CGSize)collectionViewContentSize
    {
        CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];
        for (NSInteger i = 1; i < XMGDefaultColumnCount; i++) {
            // 取得第i列的高度
            CGFloat columnHeight = [self.columnHeights[i] doubleValue];
    
            if (maxColumnHeight < columnHeight) {
                maxColumnHeight = columnHeight;
            }
        }
        return CGSizeMake(0, maxColumnHeight + XMGDefaultEdgeInsets.bottom);
    }
    
    @end
    

    ViewController.m

    #import "ViewController.h"
    #import "XMGWaterflowLayout.h"
    
    @interface ViewController () <UICollectionViewDataSource>
    
    @end
    
    @implementation ViewController
    
    static NSString * const XMGShopId = @"shop";
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // 创建布局
        XMGWaterflowLayout *layout = [[XMGWaterflowLayout alloc] init];
    
        // 创建CollectionView
        UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
        collectionView.dataSource = self;
        [self.view addSubview:collectionView];
    
        // 注册
        [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:XMGShopId];
    }
    #pragma mark - <UICollectionViewDataSource>
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
        return 50;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:XMGShopId forIndexPath:indexPath];
    
        cell.backgroundColor = [UIColor orangeColor];
    
        NSInteger tag = 10;
        UILabel *label = (UILabel *)[cell.contentView viewWithTag:tag];
        if (label == nil) {
            label = [[UILabel alloc] init];
            label.tag = tag;
            [cell.contentView addSubview:label];
        }
    
        label.text = [NSString stringWithFormat:@"%zd", indexPath.item];
        [label sizeToFit];
    
        return cell;
    }
    @end
    

    10.oc与js的交互
    (1)在oc中执行js代码:
    webViewDidFinishLoad方法中

    [webView stringByEvaluatingJavaScriptFromString:str1];
    

    (2)在网页中执行OC的方法

    -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
        NSString *str = request.URL.absoluteString;
        NSRange range = [str rangeOfString:@"xmg://"];
        if (range.location != NSNotFound) {
            NSString *method = [str substringFromIndex:range.location + range.length];
            NSLog(@"%@", method);
           SEL sel = NSSelectorFromString(method);
           [self performSelector:sel];
        }
        return YES;
    }
    

    11.本地化存储
    (1)属性列表
    (2)偏好设置
    (3)归档

    遵循NSCoding协议
    - (void)encodeWithCoder:(NSCoder *)encode{
          [encode encodeObject:self.name forKey:@"name"];
    }
    
    -  (id)initWithCoder:(NSCoder*)decode{
        self.name = [decode decoderObjectForkey];
    }
    

    (4)FMDB

    1)  获取数据库对象
    2)打开数据库,如果不存在,则创建并且打开。
    3)创建表
    4)插入数据
    5)查询数据
    

    12.性能优化
    (1)首页启动速度

    1)启动过程中做的事情越少越好
    2)不在UI线程做耗时的操作
    

    (2)页面浏览速度

    1)数据的分页
    2)   内容缓存
    3)延时加载tab(比如app有5个tab,可以先加载第一个显示的tab,其他的在显示时候加载)
    4)算法的优化(联系人姓名用汉语拼音的首字母排序)
    

    相关文章

      网友评论

          本文标题:iOS面试题

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