iOS试题集含答案

5 阅读24分钟

一、 单选题****

  1. 以下哪个是Objective-C的动态特性?

A. 静态类型
B. 方法调用时的动态绑定
C. 编译时确定方法实现
D. 不支持运行时修改类结构
答案:B
解析:Objective-C通过Runtime实现动态方法绑定,运行时通过objc_msgSend动态查找方法实现。

  1. 以下哪个是Objective-C的Runtime特性?

A. 可以在运行时动态添加方法
B. 可以在编译时修改类结构
C. 不支持动态消息转发
D. 无法交换方法实现
答案:A
解析:Runtime允许动态添加方法、交换方法实现、动态消息转发等。

  1. 在Swift中,@escaping关键字的作用是?

A. 标记闭包不逃逸当前作用域
B. 标记闭包逃逸当前作用域
C. 强制闭包同步执行
D. 禁止闭包捕获外部变量
答案:B
解析:@escaping表示闭包可能逃逸当前作用域(如异步回调)。

  1. 以下哪个不是iOS的内存管理机制?

A. ARC
B. MRC
C. 引用计数
D. 垃圾回收
答案:D
解析:iOS使用ARC(自动引用计数)和MRC(手动引用计数),无垃圾回收机制。

  1. 在Objective-C中,@property的nonatomic属性表示?

A. 线程安全
B. 非原子性访问,性能更高
C. 自动合成getter/setter
D. 不生成ivar
答案:B
解析:nonatomic不保证线程安全,但性能更高;atomic保证线程安全。

  1. 在Swift中,defer语句的作用是?

A. 延迟执行代码
B. 在函数返回后执行
C. 在异常抛出后执行
D. 在循环结束后执行
答案:B
解析:defer中的代码会在当前作用域结束时(如函数返回)执行。

7.下列代码的执行输出结果是?

func testDefer() {

    defer {

        print("方法中defer内容")

    }

    if true {

        defer {

            print("if 中defer内容")

        }

        print("if中最后的代码")

    }

    print("方法中的代码")

    if true {

        return

    }

    print("方法结束前最后一句代码")

}

A.

if中最后的代码
if 中defer内容
方法中的代码
方法中defer内容

B.

if中最后的代码

方法中的代码
if 中defer内容
方法中defer内容

C.

if中最后的代码
if 中defer内容
方法中的代码
方法中defer内容

方法结束前最后一句代码

D.

if中最后的代码

方法中的代码
方法中defer内容

if 中defer内容
答案:A
解析:defer中的代码会在当前作用域结束时(如函数返回)执行。 

  1. 以下哪个是Objective-C的关联对象(Associated Object)的作用?

A. 动态添加属性
B. 修改类方法
C. 实现多重继承
D. 替代KVO
答案:A
解析:关联对象用于动态给类添加属性,常用于Category扩展。

  1. 在Swift中,guard语句的作用是?

A. 替代if语句
B. 提前退出作用域
C. 捕获异常
D. 强制解包
答案:B
解析:guard用于提前退出作用域(如函数、循环),常用于条件判断。

  1. 以下哪个是Objective-C的弱引用关键字?

A. __weak
B. __strong
C. __unsafe_unretained
D. 以上都是
答案:A
解析:__weak用于弱引用,避免循环强引用。

  1. 在Swift中,@autoclosure的作用是?

A. 自动闭包
B. 延迟执行
C. 强制解包
D. 以上都是
答案:A
解析:@autoclosure将表达式转换为闭包,延迟执行。

  1. 在Swift中,@discardableResult的作用是?

A. 忽略返回值
B. 强制使用返回值
C. 标记结果可丢弃
D. 以上都是
答案:A
解析:@discardableResult允许忽略函数返回值,避免编译警告。

  1. 以下哪个是Objective-C的动态消息转发机制?

A. resolveInstanceMethod:
B. forwardingTargetForSelector:
C. methodSignatureForSelector:
D. 以上都是
答案:D
解析:动态消息转发通过这三个方法实现。

  1. 在Swift中,@objc的作用是?

A. 允许Objective-C调用
B. 强制解包
C. 标记私有属性
D. 以上都是
答案:A
解析:@objc用于暴露Swift代码给Objective-C。

15.关于Swift结构体(Struct)和类(Class)的区别,错误的是:

A. 结构体是值类型,类是引用类型

B. 类支持继承,结构体不支持

C. 结构体可以有析构器(deinit)

D. 类可以被多次引用,结构体赋值时会发生拷贝

答案:C

16. UIViewController的生命周期中,哪个方法只调用一次,适合做一次性初始化工作?

A. viewWillAppear

B. viewDidLoad

C. viewDidAppear

D. loadView

答案:B 

17. 关于iOS的响应者链(Responder Chain),以下描述错误的是:

A. UIResponder是所有响应者对象的基类

B. 事件将沿着响应者链向上传递,直到被处理

C. 如果一个View不处理事件,它会将事件传递给它的父视图

D. 响应者链的顶端是UIWindow

答案:D 

18. UITableView的重用机制是为了解决:

A. 滑动流畅性问题

B. 内存占用过高问题

C. 数据和视图同步问题

D. A和B

答案:D 

19. 以下哪种情况会触发离屏渲染(Offscreen Rendering)?

A. 设置layer.cornerRadius

B. 设置layer.cornerRadius且layer.masksToBounds = true

C. 设置backgroundColor

D. 设置frame

答案:B 

20. Grand Central Dispatch (GCD) 中,哪个队列的优先级最高?

A. DispatchQueue.main

B. DispatchQueue.global(qos:.background)

C. DispatchQueue.global(qos: .userInteractive)

D. DispatchQueue.global(qos: .utility)

答案:C 

21. 在GCD中,如何向全局并发队列提交一个异步任务?

A. DispatchQueue.main.async { … }

B. DispatchQueue.sync { … }

C. DispatchQueue.global().async { … }

D. DispatchQueue.serial().async { … }

答案:C 

22. 关于Operation和OperationQueue,以下说法正确的是:

A. 它们是基于GCD的更高层封装

B. 它们不支持任务间的依赖关系

C. 它们无法取消已提交的任务

D. 它们只能在主线程上运行

答案:A 

23. Swift中,如何解决类实例之间的循环强引用?

A. 使用weak关键字声明弱引用

B. 使用unowned关键字声明无主引用

C. 将引用设置为nil

D. A和B

答案:D 

24. 关于内存管理,ARC的作用是:

A. 自动清理磁盘空间

B. 自动管理引用计数,在适当的时候释放对象内存

C. 自动修复内存泄漏

D. 自动处理循环引用

答案:B 

25. 在Swift中,闭包(Closure)是:

A. 引用类型

B. 值类型

C. 既不是引用类型也不是值类型

答案:A 

26. 如果一个闭包可能在函数返回后才被调用,应该用什么关键字标记?

A. @nonescaping

B. @escaping

C. @autoclosure

答案:B 

27. 以下哪个不是iOS本地数据持久化的方案?

A. UserDefaults

B. Keychain

C. Core Data

D. NSCachedURLResponse

答案:D 

28. HTTP和HTTPS的主要区别是:

A. HTTPS速度更快

B. HTTPS对传输内容进行了加密,更安全

C. HTTP是TCP协议,HTTPS是UDP协议

D. 没有区别

答案:B 

29. 在Xcode中,用于检测内存泄漏和性能问题的工具是:

A. Debug Navigator

B. Instruments

C. Asset Catalog

D. Interface Builder

答案:B 

30. 以下哪个是Swift包管理器?

A. CocoaPods

B. Carthage

C. Swift Package Manager (SPM)

D. Homebrew

答案:C 

31. 处理App国际化(Internationalization & Localization)时,字符串应该放在:

A. 代码里直接写

B. 一个独立的Swift文件中

C. Localizable.strings文件里

D. Info.plist里

答案:C 

32. 推送通知(Push Notification)的流程中,APNs指的是:

A. Apple Push Notification service

B. Apple Phone Number service

C. A Personal Notification server

答案:A 

33. 在Swift中,@State 属性包装器的作用是:

A. 声明一个全局状态

B. 声明一个视图的局部、可变状态,当其改变时更新视图

C. 声明一个计算属性

D. 声明一个常量

答案:B 

34. #available关键字用于:

A. 检查设备型号

B. 检查系统版本,实现API可用性检查

C. 检查网络是否可用

D. 检查磁盘空间

答案:B 

35. lazy关键字修饰的属性:

A. 是线程安全的

B. 必须在声明时初始化

C. 是计算属性

D. 其初始值直到第一次被访问时才会被计算

答案:D 

36. dynamic关键字的作用是:

A. 让Swift的属性或方法能够被Objective-C运行时动态分发

B. 让变量可以动态改变类型

C. 提高代码性能

D. 声明一个动态库

答案:A 

37. 在KVO(键值观察)中,被观察的属性需要用哪个关键字修饰?

A. @objc dynamic

B. @observable

C. @KVO

D. @property

答案:A 

38. Codable协议的作用是:

A. 数据加密解密

B. 将对象序列化和反序列化为JSON或其他格式

C. 编写可解码的代码

D. 网络编码

答案:B 

39. @frozen枚举的作用是:

A. 表示枚举是冻住的,不能使用

B. 表示枚举的内存布局是稳定的,编译器可以进行优化

C. 表示枚举case是固定的,未来不会添加新的case

D. B和C

答案:D

40.Objective-C 中 isa 指针的作用是?
A. 指向对象的父类
B. 指向对象所属的类
C. 指向对象的属性
D. 指向对象的协议

答案:B

41.Instruments 工具中的 Time Profiler 用于?
A. 内存泄漏检测
B. CPU 性能分析
C. 网络请求分析
D. UI 层级查看

答案:B 

42.内存泄漏主要由什么引起?
A. 网络错误
B. 循环引用
C. UI 渲染过慢
D. 磁盘不足

答案:B 

43.iOS 中单元测试框架是? 

A. XCTest 

B. JUnit  

C. Mocha 

D. Jasmine
答案:A 

44.UITableViewCell 重用机制的核心是? 

A. 缓存图片 

B. 通过 reuseIdentifier 复用 Cell  

C. 每次都新建 Cell  

D. ARC 自动优化
答案:B 

45.AutoLayout 约束冲突时,系统会? 

A. 崩溃 

B. 自动移除部分约束 

C. 忽略所有约束 

D. 进入调试模式
答案:B 

46.iOS 响应链传递顺序是? 

A. UIApplication → UIWindow  → UIView 

B. UIApplication → UIWindow  → UIViewController 

C. UIView  → UIWindow → UIApplication 

D. UIView  → UIViewController → UIWindow →  UIApplication    
答案:D

47.GCD 中 dispatch_async 的特点是? 

A. 同步执行 

B. 异步执行,不阻塞当前线程 

C. 必须在主线程执行 

D. 会阻塞队列
答案:B 

48.KVO 的实现依赖于? 

A. Method Swizzling 

B. isa-swizzling(动态生成子类) 

C. Runtime hook 

D. 手动通知
答案:B 

49.iOS 中自动释放池 @autoreleasepool 的作用是? 

A. 延长对象生命周期 

B. 提前释放对象 

C. 统一管理延迟释放对象 

D. 防止循环引用
答案:C

50.unowned 和 weak 的区别是? 

A. weak 必须是 Optional可选型,unowned 可以是非 Optional 可选型

B. weak 不会释放对象,unowned 会释放 

C. weak 更安全,unowned 不安全 

D. 两者完全相同
答案:A

51.Objective-C 中 id 类型表示? 

A. 任意对象指针类型 

B. 任意整数类型 

C. 任意字符串类型 

D. 任意函数类型
答案:A

 

二、判断题****

  1. Objective-C的@property默认是nonatomic。

答案:正确
解析:@property默认是nonatomic,线程不安全但性能更高。

  1. GCD的DispatchQueue.main是串行队列。

答案:正确
解析:主队列是串行队列,确保UI操作按顺序执行。

  1. Objective-C的__weak引用不会增加对象的引用计数。

答案:正确
解析:__weak引用不增加引用计数,避免循环强引用。

  1. Objective-C的__weak引用在对象释放后会自动置为nil。

答案:正确
解析:__weak引用在对象释放后自动置为nil,避免野指针。

5. 在Swift中,协议(Protocol)只能定义方法,不能定义属性。

答案:错误

6. Swift的类不支持多继承,但可以通过协议实现类似的功能。

答案:正确

7. Swift中的泛型只能用于函数,不能用于类型(如类、结构体)。

答案:错误

8. iOS的响应者链(Responder Chain)从最顶层的UIWindow开始。

答案:错误

9. Auto Layout的约束冲突会导致运行时崩溃。

答案:错误

10. 离屏渲染(Offscreen Rendering)一定会导致性能问题,应该完全避免。

答案:错误

11. GCD的全局并发队列(Global Concurrent Queue)默认是串行的。

答案:错误

12. 循环引用(Retain Cycle)只会发生在两个对象之间。

答案:错误

13. UserDefaults适合存储大量数据,如图片、视频等。

答案:错误

14. Core Data是一个关系型数据库,与SQLite没有区别。

答案:错误  

15. Swift中,访问控制级别private表示只能在当前类中访问。

答案:正确

16. map、filter、reduce是Swift中的高阶函数。

答案:正确

17. try?会将错误转换为可选值,如果发生错误,返回nil。

答案:正确

18. 类型别名(Type Alias)不会创建新类型,只是为现有类型提供一个别名。

答案:正确

19. 运算符重载(Operator Overloading)可以改变现有运算符的优先级和结合性。

答案:错误

20. 扩展(Extension)可以为现有类型添加新的存储属性。

答案:错误

21. 动态派发(Dynamic Dispatch)的效率总是低于静态派发(Static Dispatch)。

答案:正确

22. Keychain是iOS中用于安全存储敏感数据的地方。

答案:正确

23. Method Swizzling是一种安全且推荐使用的技术,可以随意使用。

答案:错误

24. 通用链接(Universal Links)使用标准的HTTP/HTTPS链接来打开App。

答案:正确

25. 实现App内购买(In-App Purchase)必须使用StoreKit框架。

答案:正确

26. Combine框架是Apple提供的响应式编程框架。

答案:正确

27. Actor是Swift中用于并发编程的类型,可以防止数据竞争。

答案:正确

28.SwiftUI 中的 body 属性是存储属性。

答案:错误 它是计算属性

29.Objective-C 中每个对象都有一个 isa 指针。

答案:正确

30.RunLoop 只能在主线程使用,子线程不能使用。

答案:错误

31.Objective-C 中 nil 给对象发送消息不会崩溃。

答案:正确

32.unowned 引用对象释放后访问会崩溃。

答案:正确

33.SwiftUI 界面更新是声明式的,不需要手动刷新。

答案:正确

34.信号量(Semaphore)可以控制并发数量。

答案:正确

35.GCD 的主队列是串行队列。

答案:正确

36.final class可以防止被继承

答案:正确

37.protocol中定义的属性默认是{ get set }可读写。

答案:错误(需显式声明,默认只读)

38.@autoreleasepool可手动释放临时对象。

答案:正确

39.Bitcode是编译后的中间代码,可优化大小。

答案:正确

40.在iOS中,可通过NSNotificationCenter实现跨类通信。

答案:正确

41.guard let解包失败时程序会崩溃

答案:错误

42.Swift中==和===的区别是前者比较值,后者比较引用地址

答案:正确

43.@autoclosure属性可以将表达式自动转换为闭包

答案:正确

44.Swift的Protocol可以定义静态方法

答案:正确

45.Objective-C中id类型可以指向任何对象,无需类型转换

答案:正确

44.inout 参数的行为类似于C语言中的传递指针,它直接将内存地址传递给函数。

答案:错误

解析:inout 参数传递的是“值进入,值传出”,并非直接传递地址。它可以像引用一样修改外部变量,但其实现机制(拷贝-in拷贝-out)与传递指针有区别。

45.Swift 的 optional 类型本质是一个枚举(Enum),包含 some 和 none 两个 case。

答案:正确 

解析:Optional 的定义是 enum Optional { case none; case some(Wrapped) }。

46.String 和 Array 在 Swift 中都是值类型

答案:正确  

解析:String, Array, Dictionary, Set 都是值类型。

47.some 关键字(不透明类型)主要用于返回遵循某个协议的具体类型,但隐藏具体类型信息。

答案:正确

48.Swift 的 actor 类型通过串行执行其成员方法来确保数据隔离和线程安全。

答案:正确 

解析:这是 Swift 并发中 actor 的主要特性,它通过隔离数据来防止数据竞争。

49.在 Swift 中,循环引用(Retain Cycle)只会发生在类实例之间,值类型之间不会发生。

答案:正确 

解析:值类型在赋值时是拷贝,没有引用关系,因此不会产生循环引用。

50.自动引用计数(ARC)只管理引用类型(Class)的内存,不管理值类型(Struct, Enum)的内存。

答案:正确 

解析:ARC 的“引用计数”只适用于引用类型。值类型由系统管理其内存,通常在栈上分配和销毁。

51.使用 lazy 关键字修饰的属性,其初始化过程是线程安全的。

答案:错误  

解析:lazy 属性的初始化器在首次访问时调用,Swift 不保证这个过程是线程安全的。如果需要,应自行添加同步机制。

52.ViewController 的 viewDidLoad 方法在其视图被添加到窗口后调用。

答案:错误  

解析:viewDidLoad 在视图控制器加载其视图层次结构到内存后调用,此时视图还未添加到窗口。添加到窗口后调用的是 viewDidAppear。

53.frame 和 bounds 都是 CGRect 类型,frame 是相对于父视图坐标系的,而 bounds 是相对于自身坐标系的。

答案:正确 

54.使用 UIImage(named:) 方法加载图片会缓存图片数据,而 UIImage(contentsOfFile:) 不会。

答案:正确

解析:UIImage(named:) 会使用系统缓存,适合频繁使用的资源。UIImage(contentsOfFile:) 直接从路径读取,无缓存,适合大图或一次性图片。

55.deinit 方法在 ARC 将对象内存释放后调用。

答案:错误

解析:deinit 在 ARC准备释放对象内存之前调用,此时实例还未被释放。

56.didSet 属性观察器在初始化方法(init)中设置属性值时不会被调用。

答案:正确

解析:属性观察器 didSet 和 willSet 在初始化方法中设置属性值时不会被调用。

57.响应链(Responder Chain)是 Cocoa Touch 中处理事件的一种机制,事件从初始对象向上传递到 UIApplication。

答案:正确

解析:响应链从第一响应者开始,依次向上传递(如 view -> viewController -> window -> application),直到有对象处理该事件。

58.在 Swift 和 Objective-C 混编项目中,Swift 类要暴露给 Objective-C 代码,需要继承自 NSObject 或用 @objc 修饰。

答案:正确

59.lazy var 存储属性不能拥有 didSet 属性观察器。

答案:错误

解析:可以拥有。lazy var 是存储属性,完全支持属性观察器。

 

三、简答题****

1. 简述Swift中协议(Protocol)和类的区别。

答: 区别是协议只声明接口,不提供实现;类可以提供具体实现。

2. 什么是响应者链(Responder Chain)?它是如何工作的?

答:响应者链是由响应者对象组成的层次结构。事件首先发送给初始响应者,如果它不处理,就传递给下一个响应者,直到UIApplication对象。

3. 简述UITableViewCell的重用机制原理和目的。

答: 原理是通过重用标识符从重用池中获取可复用的Cell。目的是避免频繁创建和销毁Cell,提升性能并降低内存占用。

4. Objective-C 中 Category 和 Extension 的区别?
答:Category 可以给类添加方法但不能添加实例变量;Extension 常用于类的私有扩展,可添加属性和方法。

5.什么是动态派发(Dynamic Dispatch)和静态派发(Static Dispatch)?

答: 静态派发在编译时确定要调用的方法地址,效率高。动态派发在运行时根据对象的实际类型来确定要调用的方法地址,支持多态,效率稍低。

6.Objective-C 中 id 和 instancetype 的区别?
答:id 表示任意对象,编译期不检查类型;instancetype 表示返回当前类或其子类实例,编译期更安全。

7.iOS 中常见的循环引用场景有哪些?
答:闭包(closure)捕获 self、delegate 强引用、Timer/Notification 使用不当等。

8.autoreleasepool 的作用是什么?
答:在合适的时机延迟释放对象,降低内存峰值,用于循环创建临时对象时释放内存。

9.KVC 的实现原理?
答:通过字符串 key 动态查找 setter/getter 方法,若无则访问实例变量。

10.KVO 的实现原理?
答:Runtime 动态生成子类,重写 setter 方法,在修改属性时通知观察者。

11.Objective-C 消息发送机制是什么?
答:调用方法时会转为 objc_msgSend,通过 isa 找类的方法缓存、方法列表,若找不到进入消息转发流程。

12.RunLoop 的作用?
答:保持线程存活,处理事件(触摸、定时器、网络),节省资源。

13.RunLoop 的常见应用场景?
答:保持子线程常驻、延迟执行任务、监控卡顿、图片懒加载等。

14.UIView 和 CALayer 的关系?
答:UIView 负责事件处理和响应,CALayer 负责绘制和渲染,UIView 内部有一个根 Layer。

15.frame 和 bounds 的区别?
答:frame 是相对父视图的坐标系,bounds 是相对自身的坐标系。

16.如何减少 TableView 的卡顿?
答:预估高度、异步加载图片、复用 cell、减少层级。

17.卡顿监控的常见实现原理?
答:通过 RunLoop 监听主线程是否长时间卡在某个状态。

  1. iOS 沙盒机制的作用?
    答:隔离应用数据,防止互相访问,提高安全性。

  2. Swift 的 Optional 有什么作用?
    答:表示变量可能有值也可能为 nil,避免野指针,提高类型安全性。

20.ARC 的工作原理是什么?
答:编译器自动插入 retain/release 代码管理引用计数,当引用计数为 0 时对象被释放。

21.如何解决闭包中的循环引用?
答:使用 [weak self] 或 [unowned self] 捕获 self。

22.结构体的方法若需修改属性,需要怎么做?

答:方法需标记为 mutating

23.解释「同步」(Sync)和「异步」(Async)任务派发的区别。

答:async:异步派发。将任务添加到队列后,函数立即返回,不等待任务执行完成。不会阻塞当前线程。

sync:同步派发。将任务添加到队列后,函数会等待任务执行完成后再返回。会阻塞当前线程,直到任务完成。需谨慎使用,以免引起死锁。

24.对比 GCD 和 OperationQueue,它们各自的优势和适用场景是什么?

答:

GCD:更轻量级,C API,执行简单任务(派发到全局队列或主队列)代码简洁。

OperationQueue:基于 GCD 构建的面向对象抽象。提供更丰富的功能:

依赖关系(Dependencies):可以设置操作之间的执行顺序。

取消操作(Cancellation):可以取消单个或所有排队或正在执行的操作。

状态查询(KVO):可以监听操作的状态(isReady, isExecuting, isFinished, isCancelled)。

最大并发数(maxConcurrentOperationCount):可以方便地控制并发数量(实现串行队列效果)。

25.draw(_ rect: CGRect) 和 setNeedsDisplay() 方法的作用和调用时机是什么?

答:draw(_ rect: CGRect):是 UIView 的方法,用于自定义视图的绘制内容(使用 Core Graphics)。系统会自动调用它。

setNeedsDisplay():标记视图的某部分需要重绘。调用后,系统会在下一个绘制周期调用 draw(_:) 方法。

26. 「通知」(Notification)和「委托」(Delegate)模式分别适用于什么场景?

答:委托(Delegate):适用于一对一的通信。关系紧密,通常有明确的层级或所属关系(如 UITableView 和它的 delegate)。

通知(Notification):适用于一对多的、松耦合的通信。发送者不需要知道谁接收,接收者也不需要知道发送者是谁(通过 NotificationCenter 广播)。

27.简述 RunLoop 与线程的关系。

答:每个线程(包括主线程)都有且只有一个对应的 RunLoop。主线程的 RunLoop 默认是开启的。子线程的 RunLoop 需要手动获取(RunLoop.current)和运行(run)。

28.解释 Swift 中「写时复制」(Copy-on-Write) 的实现原理及其对于值类型的意义。

答:「写时复制」是一种优化技术。当值类型(如 Array, String) 被赋值时,底层存储并不会立即复制,而是共享同一份内存。只有当其中一个副本被修改(写入)时,才会真正进行复制操作。这减少了不必要的内存拷贝,提升了性能。

29.什么是类型别名(Type Alias)?它的作用是什么? 答: 使用typealias关键字为现有类型定义另一个名字。作用是提高代码可读性;简化复杂的类型书写。

30.什么是内存访问冲突(Memory Access Conflict)?如何避免? 答: 当同一时间对同一内存地址进行多次访问,且至少有一个是写操作时发生。避免方法是理解inout参数的访问时机;避免在函数参数中传递同一变量的多个引用。

31.什么是深链接(Deep Linking)和通用链接(Universal Links)? 答: 深链接通过自定义URL Scheme直接打开App。通用链接使用标准的HTTP/HTTPS链接来打开App。

32.Swift并发中,Task和DispatchQueue的区别? 答: DispatchQueue是GCD的队列,用于安排闭包执行。Task是Swift并发模型中的单位,用于运行异步代码。

33.Core Data和SQLite的直接使用有何不同?

答: Core Data是一个对象图管理框架,可将对象持久化到多种存储中。直接使用SQLite是操作关系型数据库,需要编写SQL语句。

34.什么是「访问控制」(Access Control)?private, fileprivate, internal, public, open 的区别是什么?

答:访问控制用于限制代码模块中的代码级别。

private:仅在当前定义的作用域内可见。

fileprivate:在当前源文件内可见。

internal:默认级别,在整个模块(App 或 Framework)内可见。

public:可以被其他模块导入使用,但不能被继承或重写。

open:可以被其他模块导入使用,并且可以被继承或重写。

35. NSCacheDictionary 在用于缓存时的主要区别是什么?

答:NSCache 是专为缓存设计的类,提供 Dictionary 没有的特性:

自动驱逐:在内存紧张时自动移除对象。

线程安全:可以在多线程环境中安全使用。

成本计算:可以为每个缓存对象指定一个「成本」,并设置总成本限制。

36.除了 weakunowned,还有哪些方法可以打破循环引用?

答:

使用「闭包捕获列表」明确指定捕获关系([weak self])。

重新设计对象之间的关系,使用「委托模式」(weak delegate)。

使用「值类型」替代引用类型来打破循环。

在适当时机手动断开引用(如 deinit 中将强引用置为 nil)。

36. 解释「竞态条件」(Race Condition) 和「死锁」(Deadlock),并各举一个 iOS 开发中的例子。

答:

竞态条件:多个线程访问共享数据且未正确同步,导致结果依赖于执行顺序。例子:两个线程同时修改同一个数组。

死锁:两个或多个线程互相等待对方持有的资源,导致所有线程都无法继续执行。例子:在主线程上同步派发任务到主队列。

37. 在 SwiftUI 中,@State, @Binding, @ObservedObject, @StateObject 分别用于什么场景?

答: 

@State:用于视图内部的私有状态,通常用于值类型。

@Binding:用于与父视图共享一个状态引用。

@ObservedObject:用于外部遵循 ObservableObject 的引用类型,通常由父视图传入。

@StateObject:用于视图内部创建和拥有的外部可观察对象,确保其生命周期与视图一致。

38. 解释 Swift 新并发框架中的 async/await 是如何工作的?

答:

async 标记一个函数是异步的。await 标记一个「挂起点」(Suspension Point)。当执行到 await 时,当前线程可能被释放去执行其他任务,而异步函数被挂起。当异步操作完成后,系统会在某个空闲线程上恢复该函数的执行。

39.actor 是什么?它是如何保证数据安全的?

答:

actor 是一种引用类型,用于在并发程序中安全地访问共享可变状态。

数据安全保证:actor 通过「数据隔离」来保证。其内部的状态(属性)只能通过其自身的方法来访问。编译器会自动确保这些方法(或 async 定义的属性)是互斥执行的(即同一时刻只有一个调用者能访问 actor 的内部状态),从而防止数据竞争。

40.draw(_ rect: CGRect) 和 setNeedsDisplay() 方法的作用和调用时机是什么?

答: 

draw(_ rect: CGRect):是 UIView 的方法,用于自定义视图的绘制内容(使用 Core Graphics)。系统会自动调用它。

setNeedsDisplay():标记视图的某部分需要重绘。调用后,系统会在下一个绘制周期调用 draw(_:) 方法。