iOS面试IOS面试集锦IOS新手进阶

OC基础

2021-01-09  本文已影响0人  水中的蓝天
IOS 开发面试必备技能图.png

什么是对象 ,OC中的对象有哪些?

对象是类的实例;是通过一个类创建出来的实例,一般称之为实例对象;OC中的常见对象有实例对象、类对象、元类对象;

什么是类?什么是元类?类对象和类,元类对象和元类有什么区别?

类: 是面向对象程序设计(OOP,Object-Oriented Programming)实现信息封装的基础。类是一种用户定义的引用数据类型,也称类类型。每个类包含数据说明和一组操作数据或传递消息的函数。类的实例称为对象
元类:以类作为其实例的类;
类对象:类本身也是一个对象,所以就有类对象;类对象可以通过实例对象的ISA指针获得
元类对象:元类本身也是一个对象,所以就有元类对象;元类对象可以通过类对象的ISA指针获得
区分二者:

什么是分类?

分类也是一个类,其底层结构和类稍有不同;给分类添加的方法会在运行时合并到原有类的方法列表(二维数组)中
分类多用来给类做扩展使用;在OC开发中应用广泛


分类.png

什么是类扩展?
类扩展:用来给类扩充私有属性、方法

什么是数组?
数组可表示为占用一块连续的内存空间用来存储元素的数据结构;OC中的数组有可变和不可变两种;可变数组做了优化利用环形缓冲区技术提高增删改查时的性能

什么是字典?
字典以键值的形式存储数据,底层实现是哈希表;OC对象作为字典的Key需要遵守NSCopying协议并且实现hash和isEqual两个方法。比如:NSNumber、NSArray 、NSDictionary、自定义OC对象 都可以作为key

什么是集合?
集合是一种用来存储数据的数据结构,内部存储的数据时无序的,其他和数组相同

OC语法有哪些?
OC中的语法有点语法.,这里的点一般转化为setter、getter方法调用

什么是Method?
Method是method_t的结构体,是对一个方法的描述:

struct method_t{
SEL name;              //函数名/方法名
const char *types;//编码(返回值类型、参数类型)
IMP imp;                //指向函数的指针(函数地址)
}

什么是内敛函数?

在普通函数(非成员函数)函数前面加上inline关键字使之成为内联函数。但是必须注意必须函数体和声明结合在一起,否则编译器将它作为普通函数来对待。

inline void func(int a);

以上写法没有任何效果,仅仅是声明函数,应该如下方式来做:

inline int func(int a){return ++;}

注意: 编译器将会检查函数参数列表使用是否正确,并返回值(进行必要的转换)。

这些事预处理器无法完成的。
内联函数的确占用空间,但是内联函数相对于普通函数的优势只是省去了函数调用时候的压栈,跳转,返回的开销。我们可以理解为内联函数是以空间换时间。

什么是构造函数?
在一个类中定义一个和类名相同的函数,这个函数就是构造函数

面向对象的设计原则是什么 ?
单一责任原则开闭原则接口隔离原则依赖倒置原则里式替换原则迪米特原则

面向对象语言的三大特性是什么 ?
封装、继承、多态

OC的继承体系


OC的继承体系.png

关键字的使用标准?
ARC环境修饰OC对象用strong、copy、weak,修饰基本数据类型用assign;
静态变量用static, 修饰为常量用const
关键字

常用设计模式?

设计模式分为四类:结构型模式、创建型模式、行为型模式、软件设计原则

常用的结构型模式有:代理、装饰
常用的创建型模式有:单利、工厂
常用的行为型模式有:观察者、发布订阅模式

代理:是一种消息传递方式,一个完整的代理模式包括:委托对象、代理对象和协议。

装饰:动态地给一个类添加一些额外的职责;Category 就是实现了装饰的设计模式;Category是一个特殊的类,通过它可以给类添加方法的接口与实现;
观察者:包含通知和KVO
单利:单:唯一,例:实例;即唯一的一个实例,该实例自创建开始到程序退出由系统自动释放;单利常被当做共有类使用;

系统常见单利类
UIApplication(应用程序实例类)
NSNotificationCenter(消息中心类)
NSFileManager(文件管理类)
NSUserDefaults(应用程序设置)
NSURLCache(请求缓存类)
NSHTTPCookieStorage(应用程序cookies池)

工厂模式:分为简单工厂模式、工厂模式、抽象工厂模式
简单工厂模式:简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。
工厂模式:抽象了工厂接口的具体产品,应用程序的调用不同工厂创建不同产品对象。(抽象产品)
抽象工厂模式:在工厂模式的基础上抽象了工厂,应用程序调用抽象的工厂发发创建不同产品对象。(抽象产品+抽象工厂)

懒加载:把初始化逻辑通过重写的方式封装起来,到需要时直接调用的方式
懒加载的优点

什么时候使用懒加载?

一般情况下,不需要使用懒加载,懒加载未必能增强可读性、独立性,滥用反而让可读性适得其反。简言之,就是在逻辑上,觉得现在不需要加载,而在后面某一时间段内可能会加载,就可以考虑懒加载

生产者消费者:
在编码中,有时会遇到一个模块产生数据,另外一个模块处理数据的情况,不论是为了模块间的结偶或是并发处理还是忙闲不均,我们都会在产生和处理数据的模块之间放置缓存区,作为生产和处理数据的仓库。以上的模型就是生产者消费者模型
生产者-消费者

中介者:

发布订阅模式

其实基本的设计模式中并没有发布订阅模式,上面也说了,他只是观察者模式的一个别称。但是经过时间的沉淀,似乎他已经强大了起来,已经独立于观察者模式,成为另外一种不同的设计模式。
在现在的发布订阅模式中,称为发布者的消息发送者不会将消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者。

举一个例子,你在微博上关注了A,同时其他很多人也关注了A,那么当A发布动态的时候,微博就会为你们推送这条动态。A就是发布者,你是订阅者,微博就是调度中心,你和A是没有直接的消息往来的,全是通过微博来协调的(你的关注,A的发布动态

观察者模式和发布订阅模式有什么区别?

观察者模式: 观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被激活的时候,会触发(Fire Event)观察者里的事件。

发布订阅模式: 订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Topic),当发布者(Publisher)发布该事件(Publish topic)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。常见的是用协议的方式来做

网上关于这个问题的回答,出现了两极分化,有认为发布订阅模式就是观察者模式的,也有认为观察者模式和发布订阅模式是真不一样的。

其实我不知道发布订阅模式是不是观察者模式,就像我不知道辨别模式的关键是设计意图还是设计结构(理念),虽然《JavaScript设计模式与开发实践》一书中说了分辨模式的关键是意图而不是结构。

如果以结构来分辨模式,发布订阅模式相比观察者模式多了一个中间件订阅器,所以发布订阅模式是不同于观察者模式的;如果以意图来分辨模式,他们都是实现了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新,那么他们就是同一种模式,发布订阅模式是在观察者模式的基础上做的优化升级。

不过,不管他们是不是同一个设计模式,他们的实现方式确实有差别,我们在使用的时候应该根据场景来判断选择哪个

block

为什么block一开始的内存会被分配在栈空间?
block使用会有两种情况:局部变量typedef声明
局部变量申请的内存肯定在栈空间

对象的本质?
对象的本质是结构体;
内存分配原理:以16个字节为单位且遵循了内存对齐原则向堆内存申请内存空间

isa指针?
isa指针是OC对象的第一个成员变量;isa是一个联合体结构,通过位域来存储数据;
isa最重要的作用是用于消息发送;

位域宏定义(真机环境arm64)
# if __arm64__
#   define ISA_MASK        0x0000000ffffffff8ULL
#   define ISA_MAGIC_MASK  0x000003f000000001ULL
#   define ISA_MAGIC_VALUE 0x000001a000000001ULL
#   define ISA_BITFIELD                                                      \
     uintptr_t nonpointer        : 1; 拿二进制的1位来存储  \
     uintptr_t has_assoc         : 1;                                       \
     uintptr_t has_cxx_dtor      : 1;                                       \
     uintptr_t shiftcls          : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
     uintptr_t magic             : 6;                                       \
     uintptr_t weakly_referenced : 1;                                       \
     uintptr_t deallocating      : 1;                                       \
     uintptr_t has_sidetable_rc  : 1;                                       \
     uintptr_t extra_rc          : 19
#   define RC_ONE   (1ULL<<45)
#   define RC_HALF  (1ULL<<18)

OC的内存管理原则 ?
OC中内存管理是通过引用计数管理实现的,当一个对象的引用计数为0时就会进入释放流程;ARC利用LLVM编译器动态的在合适的位置添加内存管理代码的方式帮助开发者管理内存,同时又通过runtime管理weak修饰的弱引用表;基本实现了不用开发者关心内存问题就可以进行开发;

多线程?

multithreading , 是指从软件或者硬件上实现多个线程并发执行的技术。
具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理(Multithreading)”。
多线程的调度原理可以认为是:时间片轮转调度算法,每个线程都会分配一个时间片然后大家轮着做任务,多线程执行时会快速切换时间片来完成多线程任务的执行;其实操作系统对进程、线程都是按照这种调度逻辑实现的

程序、进程、线程、例程、协程是什么?

在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体

实例的生命周期?

控制器的生命周期?
控制器的声明周期

响应者链条?

完整的触摸事件传递过程

上一篇下一篇

猜你喜欢

热点阅读