• iOS面试题总结 (二)


    • 14 OC的理解和特性

      • OC作为一个面向对象的语言,他也就具有面向对象的特点-封装,继承,多态。

      • OC是一门动态性的语言,他具有动态绑定,动态加载,动态类型。动态即就是在运行时才会做的一些事情。

      • 动态类型-即运行时才决定对象的类型,简单来说,就是id类型,他可以存储任意类型的变量,他自己本身就相当于指针,类似于void*。

      • 静态类型和动态类型--

        • 编译期间检查和运行时检查

        • 静态类型在编译期间就能检查出错误,静态类型声明代码可读性良好,动态类型只有在运行时才能发现错误。

      • 动态绑定-程序直到执行时才知道执行哪个方法,动态绑定需要做的,即就是在实例所属类确定后,将某些属性和方法绑定到实例上。

      • SEL是类方法方法的指针,他就相当于C语言中的中函数指针。SEL class_func = @selector(),OC类里面的方法都是被转换成SEL变量进行存储的,当类声明一个对象,对象调用方法时,系统会将这个方法转换成SEL,然后拿这个SEL在类方法中进行查找,我们可以手动将方法转换为SEL,然后用SEL去查找方法(performSelector)。

      • 动态加载-根据需求加载相应的资源,在iOS开发中,主要是做屏幕的适配。

    • 15 如何理解MVC设计模式

      • M指的是model层,它主要是进行一些数据的收集和存储。

      • V指的是view层,它主要是来展示一些UI方面的东西,比如说布局界面。

      • C指的是ViewController,他主要有一些业务逻辑的算法,还有一些功能的设计,Controller负责把model层的数据展示在view层,但是view层不能直接和Controller交互,这样,就需要用到代理或者Block了,model层和view层不能直接进行交互。

    • 16 如何理解MVVM模式。

      • V层指的是viewController层,从viewModel层或得数据,然后展示。

      • VM指的是viewMOdel,他是model和V层的粘合剂,说实在的,就是把MVC中ViewController中的一些业务逻辑和功能模块给抽出来。

    • 17 协议的基本概念和默认的类型

      • 协议就是一些方法,但是仅仅只是声明这些方法,但是没有实现,他可以被任意类使用,但是他并不是类,协议分为非正式协议和正式协议,非正式协议是NSObject的类别。

      • 协议的用法,当一个类遵循一个协议时,如果协议中的方法使用@optional修饰时,表示这个方法可以实现也可以不实现,但是要是使用@required修饰的话,说明这个类必须要实现这个方法。

      • 默认类型是@required,必须要实现的。

    • 18 什么是单例,单例的写法

      • 单例模式在他的核心结构中只包含一个叫单例的特殊类,他只有一个实例对象并且易于外部访问,从而实现对实例个数的控制,并且减少系统资源,如果想要实现实例对象只有一个,那么单例模式是你最好的选择。

      • 单例创建步骤

        • 创建一个类方法,名字以shared,default current开头。

        • 创建一个全局变量来保存对象的引用。

        • 判断该对象是否存在,如果没有则创建。

      • 单例写法。

        • 非线程安全的单例

           		/**
            *  非线程安全的单例
            *
            *  @return
            */
           + (instancetype)defaultPerson
           {
               //创建一个全局变量,以保存对象的引用
               static Person *person = nil;
               
               if (person == nil) {
                   
                   person = [[self alloc]init];
               }
               return person;
           }
          
        • 线程安全单例写法1 - 加了一个互斥锁

            		+ (instancetype)defaultPerson
            {
                static Person *person = nil;
                
                @synchronized(self) {
                    
                    if (person == nil) {
                        
                        person = [[self alloc]init];
                    }
                }
                return person;
            }
          
        • 线程安全单例写法2

            		+ (void)initialize
            {
                static Person *person = nil;
                
                if([self class] == [Person class])
                {
                    person = [[Person alloc]init];
                }
            
            }
          
        • 线程安全单例写法3 -- GCD,苹果推荐的

            		+ (instancetype)defaultPerson
            {
                static Person *person = nil;
                
                static dispatch_once_t onceToken;
                dispatch_once(&onceToken, ^{
                    
                    person = [[self alloc]init];
                });
                return person;
            }
          
    • 19 load方法和initialize方法的区别

      • load方法:

        • 当类被引用进程序的时候会执行这个函数
        • 一个类的load方法不用写明[super load],父类就会收到调用,并且在子类之前。
        • Category的load也会收到调用,但顺序上在主类的load调用之后。
      • initialize方法:

        • initialize的自然调用是在第一次主动使用当前类的时候
        • 和load不同,即使子类不实现initialize方法,会把父类的实现继承过来调用一遍。注意的是在此之前,父类的方法已经被执行过一次了,同样不需要super调用。
      • load和initialize有很多共同特点,下面简单列一下:

        • 在不考虑开发者主动使用的情况下,系统最多会调用一次
        • 如果父类和子类都被调用,父类的调用一定在子类之前
        • 都是为了应用运行提前创建合适的运行环境
        • 在使用时都不要过重地依赖于这两个方法,除非真正必要
    • 20 简述类目Category优点和缺点

      • 优点

        • 不要要增加子类就可以给现有类增加方法。

        • 通过类目可以对一个类的方法进行划分,有益于代码的维护,管理,提高代码的可阅读性。

        • 如果类目中的方法名称和原有类的方法名字一样,类目中的方法优先级更高,系统会优先调用类目中的方法。

      • 缺点

        • 无法向类目添加实例变量,如果需要添加实例变量,只能通过定义子类的方式;
        • 类目中的方法与原始类以及父类方法相比具有更高优先级,如果覆盖父类的方法,可能导致super消息的断裂。因此, 最好不要覆盖原始类中的方法。
    • 21 循环引用的产生原因,以及解决方法

      • 比如两个对象A和B,他们相互都持有对方作为自己的成员变量,只有自己销毁的时候,对象的引用计数才能减1,对象A依赖于对象B的销毁,对象B依赖于对象A的销毁,这样就造成了循环引用,

      • 解决方法 - 把其中一个对象使用__weak修饰,使其中一个对象编程弱对象。

  • 相关阅读:
    WebService如何抛出干净的异常
    添加引用方式抛出和捕获干净的WebService异常
    Linq 分组(group by)求和(sum)并且按照分隔符(join)分割列数据
    API & HTTP 请求调试:Postman
    .NET Transactional File Manager
    IIS发布站点错误收集
    zk删除node模式
    zk watch机制及创建node机制
    zk client获取数据
    Zookeeper CLI
  • 原文地址:https://www.cnblogs.com/ldnh/p/5483590.html
Copyright © 2020-2023  润新知