写点什么

2022 年最新 iOS 面试题(附答案)

作者:iOSer
  • 2022 年 3 月 16 日
  • 本文字数:3516 字

    阅读完需:约 12 分钟

最近大家都要准备去面试或者已经在面试的,这里我给大家准备了挺多资料,可以私信我拿,看看了解下。底下就是我整理出来的一些面试题

iOS 类(class)和结构体(struct)有什么区别?

Swift 中,类是引用类型,结构体是值类型。值类型在传递和赋值时将进行复制,而引用类型则只会使用引用对象的一个"指向"。所以他们两者之间的区别就是两个类型的区别。


举个简单的例子,代码如下


class Temperature {  var value: Float = 37.0}
class Person { var temp: Temperature?
func sick() { temp?.value = 41.0 }}
let A = Person()let B = Person()let temp = Temperature()
A.temp = tempB.temp = temp复制代码
复制代码


有想要领取免费资料的可以进裙或者加好友领取,这里有一个 iOS 交流圈:1012951431 可以来了解,分享 BAT,阿里面试题、面试经验,讨论技术,裙里资料直接下载就行, 大家一起交流学习!


有想要的面试资料或者其他资料也可以找我,欢迎咨询!需要的可自行下载


A.sick() 上面这段代码,由于 Temperature 是 class ,为引用类型,故 A 的 temp 和 B 的 temp 指向同一个对象。A 的 temp 修改了,B 的 temp 也随之修改。这样 A 和 B 的 temp 的值都被改成了 41.0。如果将 Temperature 改为 struct,为值类型,则 A 的 temp 修改不影响 B 的 temp。


内存中,引用类型诸如类是在堆(heap)上,而值类型诸如结构体实在栈(stack)上进行存储和操作。相比于栈上的操作,堆上的操作更加复杂耗时,所以苹果官方推荐使用结构体,这样可以提高 App 运行的效率。


class 有这几个功能 struct 没有的:


class 可以继承,这样子类可以使用父类的特性和方法 类型转换可以在 runtime 的时候检查和解释一个实例的类型 可以用 deinit 来释放资源 一个类可以被多次引用 struct 也有这样几个优势:


结构较小,适用于复制操作,相比于一个 class 的实例被多次引用更加安全。 无须担心内存 memory leak 或者多线程冲突问题

什么是 GCD ?谈谈你对 GCD 的理解?

GCD 是 Grand Central Dispatch 的缩写。


Grand Central Dispatch (GCD)是 Apple 开发的一个多核编程的较新的解决方法。在 Mac OS X 10.6 雪豹中首次推出,并在最近引入到了 iOS4.0。


GCD 是一个替代诸如 NSThread 等技术的很高效和强大的技术。GCD 完全可以处理诸如数据锁定和资源泄漏等复杂的异步编程问题。


GCD 可以完成很多事情,但是这里仅关注在 iOS 应用中实现多线程所需的一些基础知识。


在开始之前,需要理解是要提供给 GCD 队列的是代码块,用于在系统或者用户创建的的队列上调度运行。 声明一个队列


如下会返回一个用户创建的队列:


dispatch_queue_t myQueue =  dispatch_queue_create("com.iphonedevblog.post",  NULL);
复制代码


其中,第一个参数是标识队列的,第二个参数是用来定义队列的参数(目前不支持,因此传入 NULL)。


执行一个队列


如下会异步执行传入的代码:


dispatch_async(myQueue, ^{ [self doSomething]; });其中,首先传入之前创建的队列,然后提供由队列运行的代码块。


声明并执行一个队列


如果不需要保留要运行的队列的引用,可以通过如下代码实现之前的功能:  dispatch_async(dispatch_queue_create ("com.iphonedevblog.post", NULL), ^{ [self doSomething]; });如果需要暂停一个队列,可以调用如下代码。暂停一个队列会阻止和该队列相关的所有代码运行。  dispatch_suspend(myQueue);


暂停一个队列


如果暂停一个队列不要忘记恢复。暂停和恢复的操作和内存管理中的 retain 和 release 类似。调用 dispatch_suspend 会增加暂停计数,而 dispatch_resume 则会减少。队列只有在暂停计数变成零的情况下才开始运行。dispatch_resume(myQueue);


恢复一个队列 从队列中在主线程运行代码


有些操作无法在异步队列运行,因此必须在主线程(每个应用都有一个)上运行。UI 绘图以及任何对 NSNotificationCenter 的调用必须在主线程长进行。在另一个队列中访问主线程并运行代码的示例如下:  dispatch_sync(dispatch_get_main_queue(), ^{ [self dismissLoginWindow]; });注意,dispatch_suspend(以及 dispatch_resume)在主线程上不起作用。


使用 GCD,可以让你的程序不会失去响应. 多线程不容易使用,用了 GCD,会让它变得简单。你无需专门进行线程管理, 很棒!


  dispatch_queue_t   t1=dispatch_queue_create("1"  ,NULL);   dispatch_queue_t   t2=dispatch_queue_create("2",NULL);   dispatch_async(t1, ^{       [self print1];     });   dispatch_async(t2, ^{       [self print2];     }); 

复制代码

iOS 自动释放池是什么,如何工作 ?

当您向一个对象发送一个 autorelease 消息时,Cocoa 就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。


1、object-c 是通过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有 copy,retain 的时候引用计数都会加一, 每当碰到 release 和 autorelease 的时候引用计数就会减一,如果此对象的计数变为了 0, 就会被系统销毁.


2、NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.


3、autorelease 和 release 没什么区别,只是引用计数减一的时机不同而已,autorelease 会在对象的使用真正结束的时候才做引用计数减一.

iOS 一个 tableView 是否可以关联两个不同的数据源?你会怎么处理?

答案:首先我们从代码来看,数据源如何关联上的,其实是在数据源关联的***方法里实现的。 因此我们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据自己的需要去设置如相关的数据源。 因此,我觉得可以设置多个数据源啊,但是有个问题是,你这是想干嘛呢?想让列表如何显示,不同的数据源分区块显示?

iOS 类别的作用?继承和类别在实现中有何区别?

答案:


category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。 并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。类别主要有 3 个作用:


(1)将类的实现分散到多个不同文件或多个不同框架中。


(2)创建对私有方法的前向引用。


(3)向对象添加非正式协议。 继承可以增加,修改或者删除方法,并且可以增加属性。

从输入 url 到页面展示到底发生了什么

  • 1、输入地址

  • 2、浏览器查找域名的 IP 地址

  • 3、浏览器向 web 服务器发送一个 HTTP 请求

  • 4、服务器的永久重定向响应

  • 5、浏览器跟踪重定向地址

  • 6、服务器处理请求

  • 7、服务器返回一个 HTTP 响应

  • 8、浏览器显示 HTML

  • 9、浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS 等等)

iOS 中持久化方式有哪些?

属性列表文件 -- NSUserDefaults 的存储,实际是本地生成一个 plist 文件,将所需属性存储在 plist 文件中


对象归档 -- 本地创建文件并写入数据,文件类型不限


SQLite 数据库 -- 本地创建数据库文件,进行数据处理


CoreData -- 同数据库处理思想相同,但实现方式不同

你在开发过程中常用到哪些定时器,定时器时间会有误差吗,如果有,为什么会有误差?

iOS 中常 NSTimer、CADisplayLink、GCD 定时器,其中 NSTimer、CADisplayLink 基于 NSRunLoop 实现,故存在误差,GCD 定时器只依赖系统内核,相对一前两者是比较准时的。


误差原因是:与 NSRunLoop 机制有关, 因为 RunLoop 每跑完一次圈再去检查当前累计时间是否已经达到定时设置的间隔时间,如果未达到,RunLoop 将进入下一轮任务,待任务结束之后再去检查当前累计时间,而此时的累计时间可能已经超过了定时器的间隔时间,故会存在误差。

怎样防止指针的越界使用问题?

必须让指针指向一个有效的内存地址,


1、防止数组越界 2、防止向一块内存中拷贝过多的内容 3、防止使用空指针 4、防止改变 const 修改的指针 5、防止改变指向静态存储区的内容 6、防止两次释放一个指针 7、防止使用野指针.

iOS 你在项目中用过 runtime 吗?举个例子

Objective-C 语言是一门动态语言,编译器不需要关心接受消息的对象是何种类型,接收消息的对象问题也要在运行时处理。


pragramming 层面的 runtime 主要体现在以下几个方面:


  • 关联对象 Associated Objects

  • 消息发送 Messaging

  • 消息转发 Message Forwarding

  • 方法调配 Method Swizzling

  • “类对象” NSProxy Foundation | Apple Developer Documentation

  • KVC、KVO About Key-Value Coding


有想要领取免费资料的可以进裙或者加好友领取,这里有一个 iOS 交流圈:1012951431 可以来了解,分享 BAT,阿里面试题、面试经验,讨论技术,裙里资料直接下载就行, 大家一起交流学习!




文章到这里就结束了,你也可以私信我及时获取面试相关资料。如果你有什么意见和建议欢迎给我留言。

用户头像

iOSer

关注

微信搜索添加微信 mayday1739 进微信群哦 2020.09.12 加入

更多大厂面试资料进企鹅群931542608

评论

发布
暂无评论
2022年最新iOS面试题(附答案)_ios_iOSer_InfoQ写作平台