iOS基础面试题2019

基础概念

MVC (Model View Controller)设计模式,视图,控制器,模型负责提供数据,视图负责显示,
控制器的作用就是确保模型和视图的同步,一旦M改变,V就应该立即更新。Controll要如何显示View,取决于Model
https://baike.baidu.com/item/MVC%E6%A1%86%E6%9E%B6/9241230?fr=aladdin&fromid=85990&fromtitle=MVC
在这里插入图片描述

MVP (Model View Presenter)设计模式,视图,是从MVC演变而来,它们相通点就是Controller和Presenter
都是负责处理业务逻辑,但是它们也有很大的区别,就是把Model和View进行了分离,在MVP中,视图并不是直接使用模型,而是通过Presenter来进行的,
也就是说业务在Presenter内部,数据获取和更新在Model内部,如果视图需要更新,就需要通过Presenter;
Presenter与View的交互可以是间接的,可以通过接口来更新view,如果view较为复杂,也可以做一个adapter。
https://baike.baidu.com/item/MVP模式/10961746

在这里插入图片描述
MVVM (Model View View Model)一般用在用户控件上,该模式是使用的数据绑定基础架构,
MVVM是由MVP演变过来的,所以一些事件和命令相关的东西就放在了MVVM中的VM,其实也就是相当于MVP中的P
https://baike.baidu.com/item/MVVM/96310?fr=aladdin

在这里插入图片描述

ORM (Object Relational Mapping)对象关系映射就是一种为了解决面向对象语言与关系型数据库而存在的简易数据的映射,因为是基于对象模型的。
如iOS CoreData,.NET Entity Framework

1.Objective-C的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?

答: Objective-C的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

2. #import 跟#include 又什么区别,@class呢, #import<> 跟 #import“”又什么区别?

答:#import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的头文件,#import“”用来包含用户头文件。

3.属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用?
1)、weak

a.只能修饰派生自NSObject类或协议,因为NSObject即是类,也是协议
b.在对象的引用计数器为0时,对象的指针会自动指向nil
c.可以解决循环引用问题

2)、assign

a.可以修饰基础数据类型,也可以修饰派生自NSObject类的对象
b.在对象的引用计数器为0时,对象的指针不会自动指向nil
c.可以解决循环引用问题

3)、atomic

a.是Objective-C默认修饰的
b.原子性的
c.之所以线程安全,是因为只能编译器在生成setter和getter时,方法内部会有一个@synchronized()的同步互斥锁
d.线程不安全,是因为在多线程中操作对象时,比如:NSArray的addObject:方法,它是没有锁的,所以为了保证安全,我们必须自己加锁
e.速度慢

4)、nonatomic

a.不是Objective-C默认修饰的,需要手动添加
b.非原子性
c.线程不安全
d.速度快

5)、strong

a.Objective-C对象默认创建时,就是强引用
b.修饰Objective-C对象的,创建时为引用计数为1
c.不管是修饰可变属性还是不可变属性,只要使用了赋值号,就是增加了一个指针指向同一块内存地址

6)、copy

a.修饰不可变属性时,是浅拷贝,意思是:只要使用了赋值号,就是增加了一个指针指向同一块内存地址
b.修饰可变属性时,是深拷贝,意思是:只要使用了赋值号,就是新开辟了一块内存空间

7)、__block

a.默认情况下,局部变量只可以被block访问
b.但是用它来修饰局部变量,就可以在block代码块里修改局部变量的值,因为这个局部变量被拷贝了一份到block代码块里,如果是指针就是拷贝了一份指针

8)、__weak

a.就是将OC的对象改变成弱引用指针

9)、readwrite

创建时默认修饰的,写或不写都一样,是可读可写特性;

10)、readonly

只读属性,避免被外部的方法所修改

11)、retain

表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;

weak和assign,都是弱引用,assign一般修饰基础数据类型,weak也可以,当修饰OC对象时,在引用的对象被释放后,assign修饰的会引起野指针(Wild Pointer野指针就是对象被释放了,但是它的引用地址还存在),而weak修饰的不会。比如delegate就是用weak来修饰的,而不是assign
strong和retain,都是强引用,在ARC下基本是一样的作用,常用strong;但是在block情况下strong等于copy,retain等于assign。block务必用copy。

一个block代码块是否会造成循环引用要看这个block所属的类是对这个block什么修饰,如果是strong和copy,则这个block代码块一定是强引用,且在外部使用这个block代码块时,使用self,就一定要转换成__weak形式;或者在这个block所属的类里对这个block修饰为assign或者weak,则在外部使用这个block代码块时,self不用转换为__weak形式。

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

答: 编译时是NSString的类型;运行时是NSData类型的对象

5.常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int

答:object-c的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;NSInteger是基本数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是Long。

6.id 声明的对象有什么特性?

答:Id 声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;

7. frame和bounds有什么不同?

答:frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)
bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)

8.iOS系统的内存分配

1.栈区(stack)由编译器自动分配并释放,先进后出
2.堆区(heap)由程序员分配和释放,如果程序员不释放,在程序也就是该进程结束时,会由操作系统回收
3.全局区(也叫作静态区,static)存放全局变量和静态变量的,未初始化的存在bss段,已初始化的存放在data段
4.常量区 存放常量的,程序结束后由系统释放内存空间
5.代码区 存放程序函数的二进制代码

9.iOS事件是如何响应的?

iOS获取到了用户的“点击”这一行为后,把这个事件封装成UITouch和UIEvent形式的实例,然后找到当前运行的程序,并逐级寻找能够响应这个事件的对象,直到没有响应者响应。这个过程就叫做事件的响应链。
在这里插入图片描述
UITouch是触摸对象
UIEvent是事件对象

//根据坐标返回响应点击的对象
// recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
// 在接受者坐标系统中,循环调用 -pointInside:withEvent:. point 方法
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;  

//根据坐标返回事件是否发生在本视图内
// default returns YES if point is in bounds 
// 如果point在本视图内,则默认返回YES
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;   

分析的很好:http://www.cocoachina.com/articles/14896

10、异步绘制

我们进行UITableViewCell重用时,可以把cell的高度进行缓存,以便于下次使用时,直接读取而不用重新计算,计算消耗性能。
异步队列进行绘制UI,使用CoreGraphics框架,其中CoreText是一个文本处理引擎,我们就用这个,它的坐标系统左下角为0,0点
主要就是自定义一个UIView类,然后在 - (void)draw:(CGContextRef)context size:(CGSize)size 方法内部绘制,最后返回一张bitmap图片。

11、离屏渲染

1.当设置CALayer的圆角,alpha,阴影,光栅化,抗锯齿,渐变属性时,发触发离屏渲染机制。
2.离屏渲染就是在屏幕以外创建一个内存缓冲区并进行渲染,这很消耗性能
3.所以很多时候,我们私用的按钮的圆角,其实是图片背景

函数式编程

https://github.com/ReactiveCocoa/ReactiveCocoa
https://github.com/ReactiveX/RxSwift

iOS的GCD、NSThread、NSOperation、锁、Runloop的介绍和使用

发布了336 篇原创文章 · 获赞 124 · 访问量 65万+

猜你喜欢

转载自blog.csdn.net/u013538542/article/details/100141096