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

2024最新!!!iOS高级面试题,全!(二)

iOS应用是如何启动以及如何优化
pre-main阶段
加载动态链接器dyld到App进程
加载动态库(包括所依赖的所有动态库)
Rebase 修正内部的指针指向
Bind 修正外部指针指向 
初始化Objective C Runtime 包括oc的类、分类的注册,selector唯一性检查等
初始化代码,调用Oc类和分类的+load方法,构造器函数的调用(用attribute((constructor))修饰的函数、创建C++静态全局变量等
执行main函数后,调用didFinishLaunching方法完成初始化
对于pre-main阶段的耗时测量方法,在 Xcode 中 Edit scheme -> Run -> Auguments 将环境变量DYLD_PRINT_STATISTICS 设为1 。之后控制台会输出耗时。DYLD_PRINT_STATISTICS_DETAILS
建议应用的启动时间控制在400ms之下,并且在20s内启动,否则系统会kill app。
一般是优化main函数阶段,大多数的耗时是在自己写的代码里 
优化方法:
减少自定义的动态库数量,合并动态库,官方建议不超过6个。因为动态库的加载方式比静态库慢。如果必须依赖动态库,则把多个非系统的动态库合并成一个动态库。静态库是在编译时将库的代码打包到可执行程序中,动态库则是在运行时动态加载到程序中的。
减少Objective-C类,分类和Selector的个数,类似功能尽量合并
减少使用构造器函数
减少使用oc的load
减少c++静态全局变量
压缩资源图片,,因为在启动加载时会加载资源图片进行IO操作。所以图片小加载速度也会显著提升。
删除无用的方法和类,多用Swift Structs,因为Swfit Structs是静态分发的
延迟初始化那些不必要的UIViewController。
didFinishLaunching中,耗时操作的优化
类和方法名不要太⻓。
Load和initialize的不同
调用顺序不同,以main函数为分界,+load方法在main函数之前执行,+initialize在main函数之后执行。
子类中没有实现+load方法,子类不会调用父类的+load方法;而子类如果没有实现+initialize方法的话,也会自动调用父类的+initialize方法。
+load方法是在类被装在进来的时候就会调用,+initialize在实例化对象的时候调用,并且只会调用一次,是懒加载模式,如果这个类一直没有使用,就不回调用到+initialize方法。
@property 的本质是什么?
@property的本质是实例变量(ivar)+ 存取方法
,即 @property = ivar + getter + setter;
属性” (property)作为 Objective-C 的特性,主要用于封装对象中的数据。 Objective-C 对象数据保存为实例变量。实例变量一般通过“存取方法”来访问。 getter读取,setter写入。
@property中有哪些属性关键字?/ @property 后面可以有哪些修饰符?
atomic、nonatmoic、readonly、readwrite、assign、weak、strong、copy
什么情况使用 weak 关键字,相比 assign 有什么不同?
什么情况使用 weak 关键字?
循环引用的时候,比如: delegate 代理属性
xib的IBOutlet 控件属性一般也使用 weak
不同点:
assigin 可以修饰非 OC 对象,比如简单数据类型 int bool,weak 必须用于 OC 对象,
weak 是弱引用,被weak修饰的对象,引用计数不会加1 不会产生野指针。weak修饰的对象释放后,指针会自动被置nil,是安全的。
assign 修饰基本数据类型是安全的。如果修饰对象,会产生野指针;修饰的对象释放后,指针不会自动置空。
所以一般都是用 assign 来修饰基本类型,weak 来修饰对象
__weak  __block
通过 __weak 弱引用,来打破循环引用。
__block:__block修饰的变量可以修改。在代码块中会被retain(ARC)__weak:__weak修饰的变量不可以修改。不会在block代码块中被retain
__block不能修饰全局变量、静态变量(static)
block本质和说明
block闭包,本质上也是对象,是一段代码块,是带有自动变量的匿名函数,可以精简代码减少耦合
block使用的时候,可以作为变量使用,可以作为方法参数,也可以做为属性或实例变量
他有个特性叫变量捕获机制,(block内部会捕捉外部变量,auto局部变量直接捕获值,static修饰的变量捕获指针,全局变量不捕获)
Auto局部变量:我们平时写的局部变量,默认就带着 auto (自动变量,离开作用域就销毁)
在 Block 内部修改 外部变量 需要用 __block
使用block时要特别注意循环引用,避免互相持有对方的强引用,导致它们无法被释放,从而造成内存泄漏。 __weak来打破循环引用。
block内部如何修改变量的值
这个问题一般问的是修改局部变量的值,因为全局变量直接可以访问到,不存在修改不了的情况
如何修改局部变量的值:第一种:直接使用static修饰。第二种:局部变量改为全局变量。第三种:使用__block修饰变量
注意:只要不对变量/对象 的值进行修改 就不要去使用__block
block分类
.引用全局变量、全局静态变量、局部静态变量:Block 在全局区,属于 GlobalBlock
b.引用普通外部变量,用 copy,strong 修饰的 Block 就存放在堆区,属于 MallocBlock;
用 weak 修饰的Block 存放在栈区,属于 StackBlock
RunLoop
事件驱动/事件循环 的一个对象。没有消息需要处理时,休眠;有消息需要处理时,唤醒
main函数为什么可以一直运行而不退出?内部维护了一个主线程RunLoop
1、RunLoop与NSTimer
一个比较常见的问题:滑动tableView时,定时器不生效,因为在滑动时会切换RunLoop的mode,不在defaultmode下了,所以失效,可以放到commonmode下解决。commonMode是否使用过,怎样理解?相当于defaultmode和TrackingMode的集合
怎样保证子线程数据回来更新UI的时候不打断用户的滑动操作?
将更新UI事件放在主线程的NSDefaultRunLoopMode上执行,滑动是在UITrackingRunLoopMode上执行
一个线程对应一个runloop,主线程自动运行runloop,但是子线程的runloop需要手动运行
怎样实现一个常驻线程?
每次开辟子线程都会消耗cpu,在需要频繁使用子线程的情况下,会消耗大量的cpu,而且创建线程都是任务执行完成之后也就释放了,不能再次利用
向子线程runloop中添加空定时器保持唤醒
runtime
运行时
动态属性 objc_setAssociatedObject objc_getAssociatedObject
动态创建类 objc_allocateClassPair objc_registerClassPair
交换方法 swizzlingInstanceMethodInClass
例子:Scrollview的头部空白;
解决方法是设置其contentInsetAdjustmentBehavior属性为UIScrollViewContentInsetAdjustmentNever。但对于现存的项目来说挨个修改工作量无疑是巨大的,也容易出问题。这时候就用到Runtime了,用runtime来交换其初始化方法来统一设置这个属性就可以得到解决。
获取类的一些信息(包括属性列表,方法列表,成员变量列表,和遵循的协议列表)
//1.获取成员变量列表class_copyIvarList
//2.获取属性列表class_copyPropertyList
//3.获取方法列表class_copyMethodList
//4.获取协议列表class_copyProtocolList
设计模式
工厂模式 将创建对象的方法进行封装,调用即可创建对象
单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点。  UIApplication userdefault 
dispatch_once private static let test = .init
代理模式 UITableViewDatasource UITableViewdelegate uitexttfielddelegate等,适用于告知代理对象进行事件处理
观察者模式KVO 添加监听,发生变化时触发监听方法,使用结束后移除监听。一般是通过notificationcenter addobserver,他是一个单例,一对多的消息广播模式
kvc键值编码
架构模式
Mvc mvvm
‌MVC 通过controller来协调model和view之间的交互,将代码变得模块化
mvvm在mvc的基础上,衍生出了viewmodel来处理model的数据,复用性更高,ViewModel 处理 网络请求、数据逻辑和缓存读写等等
微服务架构,特别适合大型的项目,可以将模块单独拆分成不同的project,然后嵌入到项目中,kite有微服务架构的思想
设计原则
单一职责原则强调一个类或模块只负责一项功能,例如CALayer负责动画和视图显示,而UIView则提供显示内容和事件处理。
开闭原则要求对修改关闭,对扩展开放,例如通过使用category来实现功能的扩展。要考虑到后续的扩展性,而不是在原有的基础上来回修改
依赖倒置原则指出抽象不应该依赖于具体实现,而实现应该依赖于抽象,这有助于提高代码的灵活性和可维护性。
里氏替换原则表明子类必须能够替换其基类而不会引起程序行为的变化,这在面向对象编程中尤为重要。
接口隔离原则使用多个专门的协议来做接口隔离、而不是一个庞大臃肿的协议
UITableviewDelegate
UITableViewDataSource
迪米特法则,也称为最少知识原则,强调一个对象应当对其他对象尽可能少的依赖,以减少类与类之间的耦合。实现高聚合、低耦合 
App的优化
启动过程耗时
优化内存泄露,包括循环引用
优化闪退或卡死
优化过大图片、冗余文件
控制ipa包体积
页面流畅度
cocoapod
Swift Package Manager
Alamofire:http网络请求框架 要在Alamofire之后解析JSON,定义一个遵循Codable协议的Swift结构体或类,然后使用 JSONDecoder,可以设置 CodingKeys
11、SnapKit:autoLayout自动布局框架
12、Kingfisher:喵神王巍写的一款关于图片下载、缓存的框架。灵感取自OC里面的SDWebImage
4、RxSwift:函数响应式编程框架,是ReactiveX的swift版本,可以简化异步操作和事件/数据流
8、ObjectMapper:把json对象映射为model对象
不可变对象的copy是浅复制,mutablecopy是深复制
可变对象的copy与mutablecopy都是深复制

相关文章:

2024最新!!!iOS高级面试题,全!(二)

iOS应用是如何启动以及如何优化 pre-main阶段 加载动态链接器dyld到App进程 加载动态库(包括所依赖的所有动态库) Rebase 修正内部的指针指向 Bind 修正外部指针指向 初始化Objective C Runtime 包括oc的类、分类的注册,selector唯一性检查等…...

【C#生态园】构建你的C#操作系统:框架选择与实践

探秘C#操作系统开发框架:从框架选择到实际应用 前言 在当今信息技术高度发达的时代,操作系统开发框架为软件工程师提供了全新的可能性。本文将介绍一系列用于C#的操作系统开发框架,探讨它们的核心功能、使用场景、安装与配置方法以及API概览…...

ADB 安装教程:如何在 Windows、macOS 和 Linux 上安装 Android Debug Bridge

目录 一、ADB 介绍 二、Windows 系统安装 ADB 1. 下载 ADB 2. 解压文件 3. 验证 ADB 安装 4. 配置环境变量 5. 验证全局 ADB 使用 三、macOS 系统安装 ADB 1. 下载 ADB 2. 解压文件 3. 配置环境变量 4. 验证 ADB 安装 四、Linux 系统安装 ADB 1. 使用包管理器安装…...

java(2)方法的使用

目录 1.前言 2.正文 2.1方法的定义 2.2方法的调用过程 2.3方法的实参与形参 2.3.1形参 2.3.2实参 2.3.3参数传递 2.4方法的重载 3.小结 1.前言 哈喽大家好啊,今天博主继续带领大家学习java的基本语法,java的基础语法部分打算用六到七篇博文完…...

基于对数变换的图像美白增强,Matlab实现

博主简介:matlab图像处理(QQ:3249726188) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于对数变换的图像美白增强,用matlab实现。 一、案例背景和算法介绍 这次案例是美白算法&…...

MySQL高阶1873-计算特殊奖金

目录 题目 准备数据 分析数据 总结 题目 编写解决方案,计算每个雇员的奖金。如果一个雇员的 id 是 奇数 并且他的名字不是以 M 开头,那么他的奖金是他工资的 100% ,否则奖金为 0 。 返回的结果按照 employee_id 排序。 准备数据 Crea…...

Ngnix 在windows上的简单使用

安装 下载链接: nginx: download 选择页面中 Stable version 下的windows版本直接下载解压到本地。 运行nginx: 解压到本地后,结构如图: cmd 进入到上图的根目录,运行 start nginx ,即可开启。 打开 http://localhost 进行查看,如果正常打开nginx的测试页面,则说…...

嵌入式开发--STM32延时函数重构

在做嵌入式开发的时候,经常需要用到延时函数,STM32为我们提供了一个标准的毫秒级延时函数:HAL_Delay()。这个函数用起来很方便,括号内的数就是延时的毫秒数。 但是程序中如果需要用到看门狗的话呢,这玩意需要经常喂的…...

OpenAI最新发布的o1-preview模型,和GPT-4o到底哪个更强?

近日,OpenAI又出新作,正式推出了名为o1的新模型,这是其“推理”系列的首个成员,自然引起了业界的广泛关注。本文旨在全面剖析o1模型的核心特征、独特优势,并通过与先前版本GPT-4o的细致对比,为读者揭示这一…...

基于Python+SQLite的课程管理系统

系统需求简介 1.1需求分析 实现一个具体的课程管理系统。按照软件工程思路设计简化的专业课数据库,尽量模拟现有专业课程一个学期的选课排课原型实际情况。(注:本系统由本人单独设计、开发完成) 1.2 数据结构需求分析 课程管理…...

每日一练 | USG系统默认安全区域

01 真题题目 关于USG系统(华为的安全网关产品)的安全防火墙的默认安全区域的描述,正确的是: A. 默认安全区域可以删除 B. 默认安全区域可以修改安全级别 C. 默认安全区域不能删除,但可以修改安全级别D. 默认安全区域…...

技术老总眼中的品宣与促销:挑战与对策

在许多技术驱动的企业中,技术老总们往往对产品研发和技术创新拥有深刻的理解,然而当涉及市场营销,特别是“品宣”(品牌宣传)与“促销”时,他们的观念可能相对简单,有时甚至认为这两者没有本质的…...

[全网首篇]关于 VMSA-2024-0019 安全公告(CVE-2024-38812、CVE-2024-38813)的说明与解决方案

漏洞说明: CVE-2024-38812 CVE 描述: vCenter Server 在实现 DCERPC 协议时存在堆溢出漏洞。VMware 已将此问题的严重性评估 为临界严重性范围,CVSSv3 的最高基本分数为 9.8。 已知攻击: 具有 vCenter Server 网络访问权限…...

监控易监测对象及指标之:全面监控GBase数据库

在数字化时代,数据库作为企业核心数据资产的管理中心,其稳定性和性能直接关系到业务的连续性和企业的运营效率。GBase数据库作为高性能的分布式数据库系统,广泛应用于各类业务场景。为了确保GBase数据库的稳定运行和高效性能,对其…...

推荐五种msvcr71.dll丢失的解决方法,msvcr71.dll为什么会丢失?

当你的电脑提示msvcr71.dll丢失时是什么情况?为什么会出现这样的问题?msvcr71.dll丢失和什么有关呢?那么msvcr71.dll丢失应该如何解决呢?今天就和大家聊聊msvcr71.dll丢失的解决办法的详细解决步骤。 msvcr71.dll丢失是否与系统更…...

Java 内存模型(JMM)

JMM,全称 Java Memory Model ,中⽂释义Java内存模型 1. 概述 对于 Java 程序员来说,在虚拟机⾃动内存管理机制下,不再需要像 C/C 程序开发程序员这 样为每⼀个 new 操作去写对应的 delete / free 操作,不容易出现内存…...

用于安全研究的 Elastic Container Project

作者:来自 Elastic Andrew Pease•Colson Wilhoit•Derek Ditch 使用 Docker 启动 Elastic Stack 序言 Elastic Stack 是一个模块化数据分析生态系统。虽然这允许工程灵活性,但建立开发实例进行测试可能很麻烦。建立 Elastic Stack 的最简单方法是使用…...

STM8L101低功耗的理解

一.通过降低时钟频率来降低功耗: 规格书如图 1.code 从flash启动,主频率是16Mhz时,功耗测量2.51ma左右,对应程序如下: 2.code从flash启动,主频率是2Mhz时(上电默认值),功…...

Kotlin cancel CoroutineScope.launch的任务后仍运行

Kotlin cancel CoroutineScope.launch的任务后仍运行 import kotlinx.coroutines.*fun main() {runBlocking {val coroutineScope CoroutineScope(Dispatchers.IO)val job coroutineScope.launch {var i 0while (i < Int.MAX_VALUE) {iprintln(i)}}// 2ms 取消协程delay(…...

你是不是分不清哪些字体是商用,哪些非商用?快来看,免得莫名其妙负债。

前言 最近发现有好多小伙伴在做PPT的时候&#xff0c;都有一个很不好的习惯&#xff1a;没有调整好字体。 这里说的没有调整好字体的意思是&#xff1a;在一些公开发布的内容上使用一些可能造成侵权的字体。 字体侵权‌的后果相当严重。轻者可能面临法律纠纷&#xff0c;重者…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...