当前位置: 首页 > news >正文

ios面试八股文

​Swift 语言特性​​:请解释一下 struct和 class的主要区别。

特性​

​struct (值类型)​

​class (引用类型)​

​类型本质​

值类型 (复制时创建独立副本)

引用类型 (复制时共享同一实例)

​内存分配​

通常在栈上 (更快速)

在堆上 (需要ARC管理)

​可变性​

默认不可变 (需 mutating修饰方法)

默认可变

​继承​

不支持继承

支持单继承

​析构器​

无 deinit

有 deinit用于资源清理

​线程安全​

天然线程安全 (独立副本)

需手动同步 (多线程访问同一实例可能冲突)

​引用计数​

依赖ARC管理内存

内存管理​​:谈谈你对 ARC(自动引用计数)的理解。什么是强引用循环?如何避免?

Swift 在编译时自动插入 retain(增加引用计数)和 release(减少引用计数)指令,通过​​跟踪对象的引用关系​​自动管理内存生命周期。

解释 weak和 unowned的底层区别​​:

weak通过额外​​侧表(Side Table)​​ 实现自动置 nilunowned直接访问原始指针。.

​生命周期​​:描述一下 UIViewController的视图生命周期(例如 viewDidLoadviewWillAppearviewDidLayoutSubviews等)。在哪个方法里更新视图的布局或帧是安全的?

loadView() 创建视图层次的根视图

viewDidLoad()视图首次加载到内存

viewWillAppear(_:)视图即将出现

viewDidAppear(_:)视图完成显示

viewWillDisappear(_:)视图即将离开屏幕

viewDidDisappear(_:)视图已经离开屏幕

viewWillLayoutSubviews()视图​​即将计算子视图布局

viewDidLayoutSubviews()视图​​已完成子视图布局计算​​(frame已确定)

我们在viewDidLayoutSubviews()中更新视图布局或者帧是最安全的

​多线程​​:DispatchQueue.main.async和 DispatchQueue.global().async分别有什么作用?为什么更新UI必须在主队列进行?

DispatchQueue.main.async:从非主线程切换到主线程,确保UI操作在主线程执行

 DispatchQueue.global().async的作用:全局队列,是一个并发队列

UIKit 和 CoreAnimation 的底层代码​​未加锁​​(锁会降低性能),同一时间只允许​​主线程​​修改 UI 元素。

Objective-C 中CategoryExtension的区别是什么?Category 能否添加成员变量?如果不能,如何间接实现 “添加属性” 的效果?(考察 runtime 关联对象的理解)

category分类

用于给已经存在的类添加新方法,不能添加新的成员变量,可以有单独的文件,经常用于讲将一个庞大的类拆分为多个模块

类扩展

本质上是类的匿名分类,只能定义在类的实现文件中,可以添加私有成员变量,方法和属性

Category不能添加成员变量,因为oc的类在编译的时候就会确定内存布局,故无法添加

可以使用runtime关联对象实现,原理是将一个对象和另一个对象关联起来,可以达到添加属性的效果

关联对象本质上是通过 Runtime 函数,将一个对象(值)与另一个对象(宿主)建立关联关系,并通过唯一的 key 来标识这种关联。这种关联关系会被系统管理,当宿主对象被销毁时,关联对象也可以被自动清理。

Swift 的Optional(可选类型)是如何解决空指针问题的?请解释?!guard letif let的用法差异,以及nil coalescing??)运算符的底层逻辑。

其本质上是一个枚举类型

enum Optional<T> {case none       // 表示空值(nil)case some(T)    // 表示有值,关联值为具体数据
}

使用?声明一个可选类型,表示该变量肯为nil

!强制解包,将可选类型强制转换为非可选类型

if let 安全解包方式,判断可选值是否为nil,若有值,将值绑定到新变量并执行代码块,若为nil则跳过代码块

guard let 可选绑定-提前退出

??用于为可选值提供默认值

Objective-C 中strongweakassigncopy四种属性修饰符的区别是什么?

修饰符内存管理策略适用场景核心特点
strong强引用,会增加对象的引用计数(retain),持有对象直至自身被释放。大多数对象类型(如自定义类实例)确保对象不会被意外释放,是默认的对象修饰符。
weak弱引用,不增加引用计数,当对象被释放后,指针会自动置为 nil(避免野指针)。避免循环引用的场景(如代理 delegate不持有对象,对象销毁后自动清空指针,防止访问已释放内存导致崩溃。
assign直接赋值,不涉及引用计数,适用于基本数据类型。非对象类型(如 intfloatCGFloat 等)用于基本数据类型,若用于对象类型,对象释放后指针不会清空,可能导致野指针。
copy创建对象的副本并持有副本(copy 操作),不关心原对象的生命周期。不可变对象(如 NSStringNSArray 等)确保属性持有独立的副本,避免受原对象修改的影响。

Swift 中的inout参数和 Objective-C 的指针参数有什么异同

两者的核心目的一致:允许函数修改外部传入的变量,打破了函数参数默认的 "值传递" 限制。

Objective-C 指针参数:通过传递变量的内存地址(指针),函数可直接修改指针指向的内存数据。

Swift inout 参数:通过特殊的传递机制,使函数能够修改外部变量的值。基于 "复制 - 修改 - 写回"(Copy-In-Copy-Out)机制,并非直接操作内存地址

Objective-C 的@dynamic和 Swift 的dynamic关键字作用有何不同?(考察对动态特性的理解)

oc中的@dynamic与synthesize均用于处理属性的存取方法,但是行为完全相反

synthesize为默认行为,告诉编译器自动生成属性的存取方法,如果未显示声明,那么编译器会默认为属性生成synthesize property = _property

@dynamic告诉编译器不要自动生成存取方法和实例变量,由开发者来提供

在swift中

KVO(键值观察):Swift 的属性默认不支持 KVO,标记 dynamic 后才能被观察

隐含 @objc 的效果(自动暴露给 Runtime),且强制开启动态分发,确保成员能被 Runtime 动态修改(如方法交换)。

Swift 的Extension能否添加存储属性?如果不能,如何实现类似 “添加存储属性” 的效果?**(考察对 Swift 类型系统的理解)

扩展是不改变原有类型结构的前提下为其添加功能

扩展的核心作用是 “扩展功能” 而非 “修改结构

通过 Objective-C Runtime 的关联对象机制,为类(Class)添加 “伪存储属性”

 Objective-C 中NSObjectisKindOfClass:isMemberOfClass:有什么区别?在 Swift 中如何实现类似判断?(考察对类继承与元类的理解)

在 Objective-C 中,一切对象(包括类本身)都是 NSObject 的实例,存在两条关键的继承链

实例对象的继承链:实例对象 → 类对象(如 [Person class])→ 父类对象(如 [NSObject class])→ nil

类对象继承链:类对象 → 元类对象(Meta Class,类的 “类”)→ 父元类对象 → 根元类(Root Meta Class)→ 根类(NSObject)→ nil

调用 [obj isKindOfClass:cls] 时,会检查 obj 的整个继承链(包括自身所属类及所有父类)。

调用 [obj isMemberOfClass:cls] 时,仅检查 obj 直接所属的类(不包含父类)。

Swift 中protocolmutating关键字有什么作用?

mutating 关键字用于修饰协议中的方法,表明该方法 允许修改遵循协议的结构体(struct)或枚举(enum)的实例本身


文章转载自:

http://ec6s3swx.wfykn.cn
http://VtPXf19i.wfykn.cn
http://jLuvAb2X.wfykn.cn
http://HGHNuran.wfykn.cn
http://pHTgYO53.wfykn.cn
http://rDPLn5E2.wfykn.cn
http://0V5Heeb2.wfykn.cn
http://FsdvKTVt.wfykn.cn
http://SiUKdKmM.wfykn.cn
http://9Oh4NxBg.wfykn.cn
http://7MkX67k4.wfykn.cn
http://eSRrvV6e.wfykn.cn
http://ZHcXkihC.wfykn.cn
http://CMjZ3PHl.wfykn.cn
http://wrYLdwR6.wfykn.cn
http://jGP39EiK.wfykn.cn
http://xQJ6zCkP.wfykn.cn
http://PhjqC5is.wfykn.cn
http://9qUQ04dh.wfykn.cn
http://w1OJyjT2.wfykn.cn
http://XQpfpyZV.wfykn.cn
http://QMzyiFiZ.wfykn.cn
http://a18JObU8.wfykn.cn
http://HiUoIvjS.wfykn.cn
http://UmlFNKAy.wfykn.cn
http://fBRihDZp.wfykn.cn
http://p4cvq1T7.wfykn.cn
http://OEsPspnR.wfykn.cn
http://I49FSPYo.wfykn.cn
http://XevOZdt9.wfykn.cn
http://www.dtcms.com/a/372982.html

相关文章:

  • 硬件(五) 存储、ARM 架构与指令系统
  • SpringBoot - Spring 资源加载全解析:ResourceLoader 与 ResourceUtils 的正确打开方式
  • 【51单片机】【protues仿真】基于51单片机宠物投食系统
  • Linux学习-ARM 架构与处理器相关知识
  • 【代码】matlab-遗传算法工具箱
  • Redis 分布式锁的 Java 实现
  • Docker命令大全
  • springboot redisson 缓存入门与实战
  • Redis 主从复制、哨兵与 Cluster 集群部署
  • NLP自然语言处理:开启人机交互新时代
  • Spine文件导入Unity流程
  • 35.Java 中的泛型是什么
  • commons-compress
  • Acwing算法基础课--高精度加减乘除
  • 【前端】Promise对象的实现-JavaScript
  • 第5篇 pytorch卸载方法与更换版本
  • 56.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--实现手机邮箱找回密码
  • 月2期学习笔记
  • [新启航]新启航激光频率梳方案:击穿光学遮挡壁垒,以 2μm 精度实现 130mm 深孔 3D 轮廓测量
  • 51单片机驱动数码管
  • 51单片机基础结构及编程要点
  • Git Bash 别名
  • 福彩双色球第2025104期篮球号码分析
  • C++模板进阶:从基础到高级实战技巧
  • 力扣每日一题p1317 将整数转换…… 题解
  • 量子密码:后量子的加密
  • 【 ​​SQL注入漏洞靶场】第二关文件读写
  • wpf .netcore 导出docx文件
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的移动互联网人气氛围营造机制研究
  • 六级第一关——下楼梯