01-基础+UI面试题

作者: 面试题大神 | 来源:发表于2016-11-07 20:56 被阅读473次

    简单说一下APP的启动过程,从main文件开始说起

    程序启动分为两类:1.有storyboard 2.没有storyboard

    有storyboard情况下:
    1. main函数
    2. UIApplicationMain
        创建UIApplication对象
        创建UIApplication的delegate对象
    3. 根据Info.plist获得Main.storyboard的文件名,加载Main.storyboard 
    4. 创建UIWindow
    5. 创建和设置UIWindow的rootViewController
    6. 显示窗口
    
    没有storyboard情况下:
    1. main函数
    2. UIApplicationMain
        创建UIApplication对象
        创建UIApplication的delegate对象
    3. delegate对象开始处理(监听)系统事件
    4. 调用application:didFinishLaunchingWithOptions:方法并在其中创建UIWindow
    5. 创建和设置UIWindow的rootViewController
    6. 显示窗口
    

    简述一下UIViewController的生命周期?

    • loadView 正在加载
    • viewDidLoad 加载完成
    • viewWillAppear 界面即将出现
    • viewWillLayoutSubviews 界面将布局子控件
    • viewDidLayoutSubviews 界面已经布局子控件
    • viewDidAppear 界面已经出现
    • viewWillDisappear 界面即将消失
    • viewDidDisappear 界面已经消失
    • dealloc 界面被销毁

    loadView的作用?

    • 用于自定义Controller的View
    • 代码示例:
    - (void)loadView
    { 
        self.view = [[UIImageView alloc] init];
    }
    

    控制器通过Storyboard或者Xib创建时的注意事项?

    详细blogLink

    • 控制器通过storyboard加载,则根据storyboard的描述创建view
    • 控制器view通过xib加载,则根据nibName对应的xib创建view
    • 若没有指定nibName,则根据与控制器同名的xib创建view
    • 没有同名的xib,则根据与控制器名前缀相同不带controller的xib创建view
    • 如果都没有,则创建一个空白的xib

    xib如何动态处理view布局

    • 不使用自动布局时, xib根据控件在xib上的位置来布局
    • 使用自动布局时, xib通过约束条件来布局views
    • 使用自动布局时, 若只给控件添加了位置约束, 控件的宽高会根据内容动态调整

    frame和bounds的区别 ?

    • 相同点
      • 两者都可以用来改变View的大小
    • 不同点
      • frame还能改变View的位置, 但是bounds不能改变View的位置
      • 改变View的frame, 其子视图的坐标不变; 改变bounds, 子视图的坐标会变!
    • Demo解释:
        UIView *v1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
        v1.backgroundColor = [UIColor redColor];
        [self.view addSubview:v1];
        
        UIView *v2 = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
        v2.backgroundColor = [UIColor greenColor];
        [v1 addSubview:v2];
    

    以上代码得出的效果图:

    改变v1的bounds前

    添加代码v1.bounds = CGRectMake(0, 0, 200, 200)后的效果图:

    改变v1的bounds后
    • 解释
      • 通过以上两张效果图可以看出, v1看似改变了位置, 但如果留意两者的center点, 两者
      • 改变v1的bounds时, v1是在Center点保持不变的前提下改变尺寸的, 因而子视图的位置也会跟着一起改变
    • 为了避免对子视图的影响, 一般不建议修改bounds

    drawRect 和 layoutSubViews 有什么区别 ?

    • drawRect能够获取上下文, 主要用于绘图
    • layoutSubviews 用于布局子视图的

    iOS有几种动画,各自是什么?

    动画详解Link

    • 转场动画 (CATransition)
    • 帧动画 (CAKeyFrameAnimation)
    • 隐式动画 (CABasicAnimation)

    如何实现一个图形沿一个固定路径移动 ?

    • 步骤
      • 创建CALayer对象
      • 创建动画
      • 创建路径
      • 动画捆绑路径
      • CALayer捆绑动画
      • 释放路径
    • 代码示例:
     CALayer *redLayer = [CALayer layer];
        redLayer.backgroundColor = [UIColor redColor].CGColor;
        redLayer.frame = CGRectMake(150, 0, 100, 100);
        redLayer.cornerRadius = 50;
        [self.view.layer addSublayer:redLayer];
        
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        animation.duration = 3.f;
        animation.repeatCount = MAXFLOAT;
        
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddEllipseInRect(path, NULL, CGRectMake(0, 0, 300, 600));
        
        animation.path = path;
        [redLayer addAnimation:animation forKey:nil];
        
        CGPathRelease(path);
    

    ScrollView的contentSize能在viewDidLoad里设置么,为什么?

    • 一般情况下是可以的
    • 在使用AutoLayout的时候设置了也没用, 因为:
      • 系统会在viewDidLayoutSubviews中根据subviews的约束条件重新计算scrollview的contentSize, 并把之前的值覆盖掉

    页面间传值的方式有哪些

    (详细博客)

    • 正向传值
      • 定义属性来传值
    • 反向传值
      • 通过delegate使用代理方法
      • 使用block
      • 通过通知中心
        • 使用通知中心时, 谁要监听值的变化, 谁就注册通知
        • 特别要注意,通知的接受者必须存在
    • 正向反向都可以使用
      • 使用单例(通过单例的属性传值)

    如何自动计算Cell的高度

    • iOS8以下需要手动计算高度,然后缓存高度。
    • iOS8以上可以用self sizing cells, 完全不需要任何计算
      • 核心代码
    tableView.estimatedRowHeight = xx
    tableView.rowHeight = UITableViewAutomaticDimension
    

    CALayer和UIView的区别

    • 从属的库不同
      • UIView是UIKit的(只能iOS使用)
      • CALayer是QuartzCore的(iOS和mac os通用)。
    • 继承关系不同(==>表示继承于)
      • CALayer==>NSObject
      • UIView==>UIResponder==>NSObject,
    • 用户触摸功能不同
      • 因为UIView继承于UIResponder, 所以可以处理用户触摸功能
      • CALayer不能处理用户处理功能
    • 其他
      • UIView来自CALayer,是对CALayer的高层实现和封装
      • CABasicAnimation,CAAnimation,CAKeyframeAnimation等动画类都要加到CALayer上

    UITableview的复用机制的原理

    • 通过dequeueReusableCellWithIdentifier方法,先从复用队列里面通过Identifier查找是否有Cell可以复用
    • 如果有就复用,否则就创建新的Cell。

    UIButton与UITableView的层级结构

    • UIButton ==> UIControl ==> UIView
    • UITableView => UIScrollView ==> UIView
    • 拓展
      • 展示性的控件一般都直接继承于UIView, 例如UILabel, UIImageView
      • 响应性的控件一般先继承于UIControl, 再继承于UIView

    同一个Lable的Text如何显示不同字体和颜色

    • 使用富文本 (NSAttributedString()
    • 代码示例:
       NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"hello"];  
    // 第一个文字显示蓝色  
        [str addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0, 1)];
    //最后两个文字显示红色  
        [str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(2, 2)];
          
    // 在不同位置设置不同字体  
        [str addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:30] range:NSMakeRange(1, 3)];  
        self.label.attributedText = str;  
    

    说下webview与js的交互

    • UIWebView提供有直接调用JS方法,但是没有提供JS调用OC的方法
    • 可以用第三方实现JS调用OC,比如JavaScriptBridge,EasyJS,Coradova

    如果需要一个有序的NSDictionary应该怎么处理?

    • 取出字典所有的key, 对key进行排序
    • 按照key值顺序输出所有的Value值

    断言的使用

    • NSAssert(url != nil, @"URL不能为空");
      • 当url == nil时, 程序会报错, 报的错为"URL不能为空"

    深浅拷贝的区别和使用场景

    • 区别
      • 深拷贝是对象拷贝 -> (会创建新对象)
      • 浅拷贝是指针拷贝 -> (拷贝的是对象的地址)
    • 代码示例:
        [NSString copy];           (浅拷贝)
        [NSMutableString copy];    (深拷贝)
        
        [NSString mutableCopy];    (深拷贝)
        [NSMutableString mutableCopy]; (深拷贝)
    

    weak的使用情景?

    • 在 ARC 中,在有可能出现循环引用的时候,通过使用weak修饰来解决
    • 自身已经对它进行一次强引用,没有必要再强引用时也会使用 weak
      • 例如自定义 IBOutlet 控件属性

    assign和weak的区别?

    详细博客第12题

    • 使用领域不同
      • assign既可以用于MRC,也可以用于ARC
      • weak只用于ARC
    • 在ARC中修饰的变量类型不同
      • aasign用于修饰简单的数据类型, 如Int, BOOL等
      • weak用于修饰对象
    • 在ARC中修饰后的作用不同
      • assign修饰的变量在释放时不会置为nil, 修饰的对象会变为僵尸对象, 再次引用会引起崩溃
      • weak修饰的对象在释放时会置为nil, 再次引用不会引起崩溃

    说说 __block__weak的区别

    • 定义

      • __block告诉block拦截变量时, 拦截其地址
      • __weak 告诉block, 不要对引用的对象进行强引用(即不要对其进行retain)
    • 作用

      • 在MRC中使用__block可以解决循环引用问题, 因为截获的是对象的地址, 不会对其进行retain
      • 在MRC和ARC中使用__block, 由于引用是的地址, 因此可以在block内部修改外部的值
      • 在ARC中使用__weak可以解决循环引用问题

    instancetype与id的区别

    • 在ARC环境下:
      • 使用Instancetype时, 在编译的时候就会检查实例的类型
      • 使用id的话, 编译时不检查类型, 运行时才检查类型
    • 在MRC环境下:
      • instancetype和id一样,不做具体类型检查
    • id可以创建对象, 可以作为方法的参数类型, 但instancetype不可以
    • instancetype只适用于作为方法返回值类型

    #import和#include的区别, #import<>和 #import ""的区别, #import和@class的区别?

    • #import#include的区别
      • #include是C/C++中使用的,#import是OC中使用的
      • #include不能避免头文件被重复包含的问题, #import可以解决这个问题
    • #import<>#import ""的区别
      • #import<> 用于导入系统头文件,#import ""用于导入自己的头文件
    • #import@class的区别
      • #import会包含这个类的所有信息,包括变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,不包括变量和方法
      • .h文件中一般使用@class来声明类。 而在.m文件中,因为会用到这个类内部的变量和方法,所以需要使用#import
      • @class的编译效率比 #import
      • 如果有循环依赖关系,如:A–>B, B–>A, 使用#import来相互包含,会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。

    Objective-C中类别, 类扩展和继承的区别?

    • 作用不同
      • 类别可以用来添加新的方法, 不能添加新的属性
      • 类扩展可以添加新的属性(私有), 不能添加新方法
      • 继承可以添加新的属性, 可以重写父类的方法, 还可以添加新的方法
    • 对类的影响不同
      • 类别可以根据功能的不同, 把不同的方法分开放在几个不同的类别, 以可以减少单个文件的体积。
      • 类扩展是类的一部分,在编译时随类的生成而生成。
      • 继承相当于为原来的父类创建了一个新的子类

    如何进行代码做自动布局

    • 使用苹果自带的类NSLayoutConstranit
    • 使用可视化格式语言 (VFL)
    • 使用第三方框架 (Masonry)

    简述assign、retain、copy、weak和strong分别在什么情况下使用?

    • strong和weak在ARC中用过来修饰对象属性, 表示强弱引用
    • retain, assign在MRC中用来修饰对象属性, 表示是否进行retain(引用计数+1)
    • assign在ARC中还可以用来修饰普通类型变量
    • copy可以用来拷贝对象
    • copy用来修饰NSString变量Str, 通过浅拷贝使其他类可修改Str的值
    • copy在MRC中通过修饰Block属性, 可以使block被保存到堆上

    delegate用什么属性修饰,ARC下与MRC下有何不同,为什么?

    详细博客第8题

    • ARC中用weak, 可防止循环引用, 对象销毁后还可以将其置nil
    • MRC中用assign, 可防止循环引用

    NSString,NSArray,NSMutableArray分别用什么属性修饰,原因是什么?

    详细博客

    • NSString和NSArray用 copy, 浅拷贝, 允许外部引用时同步修改变量的值
    • NSMutableArray 用 strong进行强引用, 若使用copy, 在深拷贝的作用下反而会破坏变量的封装性

    谈一下关键字const, static和extern的作用?

    详细blogLink

    • const用于声明常量, 修饰后的变量都是只读的
    int const a = 10;
    a = 20
    //因为变量a被const修饰,就成为了只读,不能被修改赋值了,
    所以上面a = 20这行代码是错误的
    
    • static用于声明静态变量(在内存中只创建一次)
    • 注意, static声明的静态变量的作用域只存在于当前作用域 (方法/文件)
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
       static int i = 0; 
       i ++; 
       NSLog(@"i=%d",i);}
    //打印结果 (因为变量i在内存中只存在一份!)
       i = 1, i = 2, i = 3 ....
    }
    
    • extern用于声明外部全局变量或常量
    • 在.h中声明全局常量
    //声明一些全局常量
    extern NSString * const name;
    extern NSInteger const count;
    
    • 在.m中初始化常量, 这样只要导入头文件,就可以全局的使用定义的变量或常量
    #import <Foundation/Foundation.h>
    //实现
    NSString * const name = @"王五";
    NSInteger const count = 3;
    

    @property本质是什么

    详细blog链接

    • @property = ivar + getter + setter
    • 使用@property, 系统默认为完成以下操作:
      • 创建属性的“偏移量” (offset),表示该变量距离存放对象的内存区域的起始地址有多远。
      • 创建method_list (方法列表), 保存setter方法和getter方法
      • 创建ivar_list (成员变量列表)
      • 创建prop_list (属性列表)

    OC语言三大特性的定义和特点以及各自的适用场景

    封装

    • 特点
      • 可以模块化代码
    • 使用场景
      • 需要做性能优化时
      • 需要减少代码量时

    继承

    • 特点
      • 子类拥有父类的(非私有)属性+方法
    • 使用场景
      • 装饰者模式

    多态

    • 特点
      • 父类指向之类, 动态创建对象
    • 使用场景
      • 工厂模式

    在OC里面,给指定类动态添加行为的方法有哪些

    • 继承
    • 协议
    • 类别

    相关文章

      网友评论

        本文标题:01-基础+UI面试题

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