Alamofire 网络请求全流解析,通俗易懂

Alamofire 网络请求全流程解析:从发起请求到处理响应

一、请求发起阶段:准备你的"快递"

1. 你告诉Alamofire要发什么"快递"

// 就像告诉快递员:"我要寄一个包裹给https://api.example.com"
AF.request("https://api.example.com/user", method: .get, parameters: ["id": 123])

2. Alamofire准备"符合Alamofire公司的快递单"

准备阶段
检查URL是否合法
URLConvertible
添加HTTP方法
URLRequestConvertible
添加请求头
添加参数
你的请求
创建URLRequest

URLRequestConvertible.swift文件中:创建URLRequest

public protocol URLRequestConvertible {func asURLRequest() throws -> URLRequest
}
// 把你要的地址变成真正的合理的快递单

二、请求创建阶段:把包裹交给快递站

3. Session快递站接收包裹

Session快递站包裹SessionDelegateURLSession我要寄这个包裹创建DataRequest包裹登记这个包裹交给系统快递员Session快递站包裹SessionDelegateURLSession

Session.swift文件中:

func request(_ convertible: URLConvertible) -> DataRequest {// 创建包裹对象let request = DataRequest(...)// 登记包裹sessionDelegate.register(request, for: task)// 交给系统快递员task.resume()return request
}

三、网络传输阶段:包裹在路上

4. 系统快递员送包裹

网络层
TCP连接
HTTP请求
路由
路由器
你的设备
互联网
服务器

Alamofire在这一步使用系统的URLSession发送请求,就像使用专业的快递公司运送包裹。

四、响应接收阶段:包裹到达目的地

5. 服务器处理请求并返回结果

服务器系统快递员快递站管理员Request这是包裹的回执包裹状态更新更新你的包裹状态服务器系统快递员快递站管理员Request

SessionDelegate.swift中:

// 收到数据时
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {// 找到对应的包裹if let request = request(for: dataTask) {// 告诉包裹:"你收到新数据了!"request.didReceive(data: data)}
}

五、数据处理阶段:拆包裹看内容

6. Alamofire帮你拆包裹

JSON
图片
文本
原始数据
数据格式
JSONResponseSerializer
ImageResponseSerializer
StringResponseSerializer
解析为字典/数组
转换为UIImage
转换为字符串

ResponseSerialization.swift中:

public struct JSONResponseSerializer: ResponseSerializer {public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?) throws -> Any {// 把数据变成JSONreturn try JSONSerialization.jsonObject(with: validData, options: options)}
}

六、结果返回阶段:把结果交给你

7. 最终结果回到你的手中

包裹包裹处理器原始数据处理好的数据这是你的结果!包裹包裹处理器

当你这样写代码时:

AF.request(...).responseJSON { response in// 这里拿到最终结果print(response.value) // 拆开包装的内容
}

在内部是这样的:

func responseJSON(completionHandler: @escaping (AFDataResponse<Any>) -> Void) -> Self {// 添加一个"包裹处理器"appendResponseSerializer {// 处理数据...let result = Result { try JSONResponseSerializer().serialize(...) }// 把结果交给你completionHandler(DataResponse(...))}return self
}

七、完整流程图:从开始到结束

你发起请求
创建URLRequest
Session创建DataRequest
SessionDelegate注册任务
URLSession发送请求
服务器处理请求
返回响应数据
SessionDelegate接收数据
转发给DataRequest
是否有响应处理器
执行序列化
返回处理结果
保存原始数据
回调给你的代码

八、关键文件如何协作

步骤关键文件它做的事
1. 准备请求URLRequestConvertible.swift把你的请求变成标准格式
2. 创建请求Session.swift创建请求对象,交给系统
3. 发送请求URLSession (系统)真正发送网络请求
4. 接收响应SessionDelegate.swift接收系统返回的数据
5. 处理数据ResponseSerialization.swift把原始数据变成有用的格式
6. 返回结果Request.swift把最终结果交还给你

九、用快递比喻理解整个过程

  1. :顾客(想要发送或获取数据)
  2. AF.request():你填写快递单
  3. Session:快递站(管理所有包裹)
  4. DataRequest:你的包裹
  5. URLSession:真正的快递员
  6. SessionDelegate:快递站管理员(跟踪包裹状态)
  7. ResponseSerializer:包裹拆封员(打开包裹并检查内容)
  8. responseJSON:最终把包裹里的东西交给你

当你说:"请帮我从https://api.example.com/user?id=123取东西"时:

  1. Alamofire准备快递单(创建URLRequest)
  2. 把快递单交给快递站(Session)
  3. 快递站登记包裹(创建DataRequest)
  4. 真正的快递员出发(URLSession发送请求)
  5. 快递员到达服务器取件
  6. 快递员带着包裹返回
  7. 快递站管理员签收(SessionDelegate接收数据)
  8. 拆封员打开包裹(ResponseSerializer处理数据)
  9. 把里面的东西交给你(回调你的代码)

这样,你就完成了一次网络请求!Alamofire帮你处理了所有复杂的步骤,让你可以轻松获取网络数据。


1. Alamofire (根目录)

核心功能:框架入口与版本管理

  • Alamofire.swift:框架总入口,提供全局快捷方法 AF.request()

2. Core (核心引擎)

核心功能:网络基础架构实现

文件功能协作关系
Session.swift中央调度器,管理所有请求生命周期依赖 RequestSessionDelegate
Request.swift``DataRequest.swift``UploadRequest.swift``DownloadRequest.swift请求类型基类及具体实现Session 创建和管理
SessionDelegate.swiftURLSession 事件代理转发桥接系统 URLSession 和 Alamofire 请求
Result.swift统一结果封装 (Success/Failure)被所有响应处理器使用
Configuration.swift网络配置 (超时/缓存策略等)初始化 Session 时注入

3. Extensions (功能扩展)

核心功能:增强系统类型能力

文件功能协作对象
URLConvertible.swift统一 URL 类型转换被所有请求创建方法使用
URLRequestConvertible.swift标准化请求创建Session.request() 参数
HTTPHeaders.swift类型安全的 HTTP 头管理请求配置阶段使用
HTTPMethod.swiftHTTP 动词枚举请求创建时指定

典型扩展

// URLConvertible 协议允许多种输入类型
public protocol URLConvertible {func asURL() throws -> URL
}
// String/URL/URLComponents 均实现该协议
AF.request("https://api.com") // 自动转换

4. Features (高级特性)

核心功能:框架增值功能实现

(1) 安全模块
文件功能
ServerTrustManager.swiftSSL 证书绑定管理
ServerTrustEvaluating.swift证书验证策略实现
(2) 请求处理
文件功能
RequestInterceptor.swift请求拦截器 (认证/重试)
CachedResponseHandler.swift响应缓存策略
(3) 响应处理
文件功能
ResponseSerializer.swift响应数据序列化基类
JSONResponseSerializer.swiftJSON 解析实现
DecodableResponseSerializer.swiftCodable 支持
(4) 网络监控
文件功能
NetworkReachabilityManager.swift网络状态监听
EventMonitor.swift请求事件监听器

协作示例 - 证书绑定流程:

成功
失败
Session
ServerTrustManager
是否包含域名
PinnedCertificatesTrustEvaluator
DefaultTrustEvaluator
验证证书链
允许连接
终止请求

5. Supporting Files (支撑系统)

核心功能:平台适配与基础设施

文件类型功能
Info.plist框架元数据配置
Alamofire.hObjective-C 桥接头文件
module.modulemap模块映射定义
LinuxMain.swiftLinux 平台测试入口

关键协作机制分析

  1. 请求生命周期管理

    • Session 创建 Request 对象
    • SessionDelegate 监听 URLSession 事件
    • 事件通过 Request 子类处理状态转换
  2. 线程安全实现

    // 专用队列处理所有委托事件
    private let rootQueue = DispatchQueue(label: "org.alamofire.session.rootQueue")
    // 请求内部状态机使用串行队列
    private let stateQueue = DispatchQueue(label: "org.alamofire.request.stateQueue")
    
  3. 协议导向设计

    • URLConvertible:统一输入源处理
    • RequestInterceptor:分离认证逻辑
    • EventMonitor:解耦事件监听
  4. 性能优化技巧

    • 连接复用:通过共享 URLSession 实例
    • 零拷贝传输:InputStream 处理大文件
    • 懒加载:URLRequest 延迟创建

典型工作流:带认证的API请求

// 1. 创建拦截器
let interceptor = AuthenticationInterceptor(adapter: adapter, retrier: retrier)// 2. 发起请求 (使用Extensions的URLConvertible)
AF.request("https://api.com/user", interceptor: interceptor) // Features模块.validate()  // Core的Request扩展.responseDecodable(of: User.self) { // Features的Decodable序列化// 3. 处理响应
}

内部协作

  1. URLConvertible 转换输入URL
  2. RequestInterceptor 添加认证头
  3. Session 创建 DataRequest
  4. DecodableResponseSerializer 解析响应
  5. EventMonitor 记录请求时间线

以下是对 Alamofire 源码模块协作关系的全景解析,包含所有核心类及其交互关系:

Alamofire 模块协作全景图

Session
SessionDelegate
Request
Configuration
DataRequest
UploadRequest
DownloadRequest
SessionStateProvider
SessionTaskMetrics
URLConvertible
URLRequestConvertible
HTTPHeaders
RequestAdapter
HTTPMethod
ServerTrustManager
ServerTrustEvaluating
DefaultTrustEvaluator
PinnedCertificatesTrustEvaluator
RevocationTrustEvaluator
RequestInterceptor
Adapter
Retrier
CachedResponseHandler
ResponseSerializer
JSONResponseSerializer
DecodableResponseSerializer
StringResponseSerializer
NetworkReachabilityManager
EventMonitor
CompositeEventMonitor
SessionProvider
NotificationCenter

核心类关系详解

1. Session (中央调度器)
  • 协作对象

    • Request:管理所有请求实例
    • SessionDelegate:处理底层 URLSession 回调事件
    • Configuration:网络配置参数
  • 核心作用

    • 创建和管理所有网络请求
    • 实现请求的队列管理和优先级控制
    • 提供全局事件监控接口
2. SessionDelegate (代理转发器)
  • 协作对象
    • SessionStateProvider:提供会话状态信息
    • SessionTaskMetrics:收集性能指标
    • Request:转发事件到具体请求
  • 核心作用
    • 实现所有 URLSessionDelegate 方法
    • 将系统事件分发给对应的 Request 对象
    • 处理 SSL 握手和认证挑战
3. Request 继承体系
Request
+state: State
+progress: Progress
+cancel()
+resume()
+suspend()
DataRequest
+response(queue:completionHandler:)
+responseData(queue:completionHandler:)
UploadRequest
+uploadProgress(queue:closure:)
DownloadRequest
+downloadProgress(queue:closure:)
+cancel(producingResumeData:)
4. 安全模块协作
SessionSessionDelegateServerTrustManagerServerTrustEvaluating收到身份验证挑战获取评估器选择评估策略执行证书验证返回验证结果SessionSessionDelegateServerTrustManagerServerTrustEvaluating
5. 请求处理流程
重试
不重试
用户发起请求
Session
RequestInterceptor
是否适配?
Adapter修改请求
创建Request对象
SessionDelegate注册任务
URLSession执行请求
收到响应
是否失败?
Retrier决定重试
返回错误
ResponseSerializer处理
返回结果
6. 响应序列化体系
ResponseSerializer
+serialize(request:response:data:error:)
DataResponseSerializerProtocol
DownloadResponseSerializerProtocol
JSONResponseSerializer
+options: JSONSerialization.ReadingOptions
DecodableResponseSerializer
+decoder: DataDecoder
StringResponseSerializer
7. 事件监控系统
监控事件
RequestCreated
Resumed
ReceivedData
Completed
Retried
Request
EventMonitor
CompositeEventMonitor
Logger
PerformanceMonitor
CustomMonitor

关键协作机制详解

  1. 请求生命周期管理

    • Session 创建 Request 对象
    • Request 通过 SessionDelegate 注册到 URLSession
    • 事件通过 SessionDelegateRequest 传递
    • EventMonitor 全程监控状态变化
  2. 线程安全模型

    // 专用队列处理委托事件
    private let rootQueue = DispatchQueue(label: "org.alamofire.session.rootQueue")// 请求状态机使用串行队列
    private let stateQueue = DispatchQueue(label: "org.alamofire.request.stateQueue")// 原子操作保护状态
    private let protectedState: Protector<State> = Protector(State())
    
  3. 协议导向设计

    • URLRequestConvertible:统一请求创建接口
    public protocol URLRequestConvertible {func asURLRequest() throws -> URLRequest
    }
    
    • RequestInterceptor:分离认证逻辑
    public protocol RequestInterceptor: RequestAdapter, RequestRetrier {}
    
    • EventMonitor:解耦监控逻辑
    public protocol EventMonitor {func request(_ request: Request, didCreateTask task: URLSessionTask)
    }
    
  4. 性能优化关键点

    • 连接复用:通过共享 URLSession 实例
    • 零拷贝传输:InputStream 处理大文件
    open func upload(with stream: InputStream)
    
    • 延迟创建:URLRequest 在必要时创建
    • 内存优化:流式下载避免大内存占用

模块协作价值分析

  1. 核心层 (Core)

    • 提供网络基础能力
    • 实现高性能的请求管理
    • 确保线程安全和资源管理
  2. 扩展层 (Extensions)

    • 统一接口规范
    • 增强类型安全性
    • 简化API使用
  3. 特性层 (Features)

    • 模块化可插拔设计
    • 提供企业级安全能力
    • 支持复杂业务场景
    • 完善的监控诊断体系
  4. 支持系统 (Supporting Files)

    • 多平台适配保障
    • 框架元数据管理
    • 生态兼容性支持

Alamofire 的架构通过严格的职责分离和协议导向设计,实现了:

  • 扩展性:新增功能不影响核心逻辑
  • 可维护性:模块边界清晰
  • 性能:接近原生URLSession的效率
  • 开发体验:简化复杂网络操作

这种设计使Alamofire能在保持轻量级(核心仅2000行代码)的同时,提供企业级网络解决方案,成为iOS开发中最广泛使用的网络库之一。

设计哲学总结

  1. 分层架构

    • Core:网络基础
    • Extensions:协议扩展
    • Features:可插拔组件
  2. 关注点分离

    • 请求创建 vs 请求处理
    • 数据传输 vs 数据解析
    • 核心逻辑 vs 平台适配

你问的是:Alamofire 内部对一个网络请求每一步的数据流向和方法,图文和代码表示。


一、Alamofire 网络请求全流程图解

1. 流程图(简化版)

你(开发者)AlamofireSessionSessionDelegateURLSession服务器DataRequestAF.request(...)创建 DataRequest创建 URLSessionTask注册 DataRequest 与 Task 映射发送 HTTP 请求返回响应/数据回调各类事件(数据、完成、错误等)分发事件到对应请求对象响应回调(如 responseJSON)你(开发者)AlamofireSessionSessionDelegateURLSession服务器DataRequest

2. 详细步骤与关键方法

步骤1:开发者发起请求
AF.request("https://api.example.com/user", method: .get, parameters: ["id": 1])
步骤2:Alamofire 组装请求
  • 通过 Session 创建 DataRequest 对象
  • 组装 URL、参数、Header、Method
public func request(_ convertible: URLConvertible,method: HTTPMethod = .get,parameters: Parameters? = nil,encoding: ParameterEncoding = URLEncoding.default,headers: HTTPHeaders? = nil
) -> DataRequest
步骤3:Session 创建 URLSessionTask
  • 调用 URLSession.dataTask(with:) 创建底层任务
  • 通过 SessionDelegate 注册 task 与 DataRequest 的映射
let task = urlSession.dataTask(with: urlRequest)
sessionDelegate.register(dataRequest, for: task)
步骤4:URLSession 发送请求
  • 由系统底层通过 TCP 发送 HTTP 请求到服务器
步骤5:服务器返回响应
  • 服务器返回数据,系统回调 URLSessionDelegate 相关方法
步骤6:SessionDelegate 事件分发
  • SessionDelegate 收到回调(如 didReceive datadidCompleteWithError
  • 通过 taskIdentifier 找到对应的 DataRequest
  • 调用 DataRequest 的处理方法
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {if let request = requests[task.taskIdentifier] {request.didComplete(error: error)}
}
步骤7:DataRequest 处理响应
  • 解析数据、序列化 JSON、处理错误
  • 最终通过回调(如 .responseJSON)返回给开发者
AF.request(...).responseJSON { response in// 这里处理结果
}

三、代码片段串联

// 1. 用户发起请求
let request = AF.request("https://api.example.com/user", method: .get)// 2. Session 组装 DataRequest
// 3. Session 创建 URLSessionTask
// 4. SessionDelegate 注册映射
// 5. URLSession 发送请求
// 6. SessionDelegate 分发事件
// 7. DataRequest 处理响应
request.responseJSON { response inprint(response)
}

四、总结

  • 每一步的数据流向:开发者 -> Alamofire -> Session -> URLSession -> 服务器 -> URLSession -> SessionDelegate -> DataRequest -> 开发者
  • 每一步的关键方法AF.requestSession.requestURLSession.dataTaskSessionDelegate 回调、DataRequest 响应处理
  • 事件分发机制:通过 taskIdentifier 映射,实现请求与回调的精准对应

如需更详细的源码解读、流程图、或某一步的具体实现细节,欢迎随时提问!


我是一个基于claude-4-sonnet-thinking技术的AI助手,在Cursor IDE环境中工作,随时为您提供专业支持。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.tpcf.cn/diannao/91389.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

链路聚合技术

链路聚合技术 链路聚合概述及应用场景 概述 链路聚合是把多条物理链路聚合在一起&#xff0c;形成一条逻辑链路。应用在交换机、路由器、服务器间链路&#xff0c;注意了&#xff0c;主机上面不能用链路聚合技术分为三层链路聚合和二层链路聚合链路聚合的作用 增加链路带宽提供…

SpringCloud之Zuul

SpringCloud之Zuul 推荐参考&#xff1a;https://www.springcloud.cc/spring-cloud-dalston.html#_router_and_filter_zuul 1. 什么是Zuul Spring Cloud Zuul 是 Netflix 提供的微服务网关核心组件&#xff0c;作为统一的 API 入口&#xff0c;承担请求路由、过滤、安全控制等…

低精度定时器 (timer_list) 和 高精度定时器 (hrtimer)

Linux 内核提供了两种主要类型的定时器&#xff0c;以满足不同的时间精度需求&#xff1a;低精度定时器 (timer_list) 和 高精度定时器 (hrtimer)。它们各有特点和适用场景。下面&#xff0c;我将分别提供它们在内核代码中的简化使用示例。1. 低精度定时器 (timer_list) 示例ti…

虚拟机VMware的使用方法

虚拟机VMware的使用方法VMware是全球领先的虚拟化技术提供商&#xff0c;其产品&#xff08;如VMware Workstation Pro&#xff09;允许用户在单一物理机上运行多个操作系统&#xff08;OS&#xff09;&#xff0c;实现资源高效利用、隔离测试和灵活部署。本文将详细介绍VMware…

冰岛人(map)

#include<bits/stdc.h> using namespace std; struct people { string fat; int sex; }; map<string,people>mp; int pan(string s,string m) { string s1; int i0; while(s!“”) { int y0; s1m; while(s1!“”) { if(s1s&&(i<4||y<4)) return 0; s…

MS Azure Eventhub 发送 AD log 到cribl

1: 首先说一下,Cribl 提供了很多第三方的接口: 先看一下cribl 提供的接口界面: 注意到,上面提供的link 地址是 xxxxx:9093, 不鼠标放到撒谎给你吗的? 上面,就可以看到了。所以要开的port 一定要把9093 开了,关于全部开的port: What ports do I need to open on the f…

电力名词通俗解析5:计量系统

## 电网计量系统通俗讲解&#xff1a;南网视角下的电力“精算师”想象一下&#xff0c;城市电网如同一个庞大而精密的“能量河流”&#xff0c;千家万户、工厂企业都在从中取水&#xff08;用电&#xff09;。如何精确计量每家用了多少“水”&#xff1f;如何确保“河流”输送中…

关于redis各种类型在不同场景下的使用

Redis 提供了多种数据结构类型,每种类型适用于不同的场景。以下是 Redis 主要数据类型及其典型应用场景的详细说明: 1. String(字符串) 特点:最简单的键值存储,值可以是字符串、整数或二进制数据(最大 512MB)。 适用场景: 缓存:存储用户会话、网页内容等(如 SET u…

Vue 3 动态ref问题

目录 1.问题描述 2.示例代码 3.原因分析 4.解决方案 5.总结 1.问题描述 在Vue 3项目中&#xff0c;当使用动态ref来引用组件时&#xff0c;删除组件后发现ref对象中对应的key仍然存在&#xff0c;只是值变为null&#xff0c;而不是完全删除该key。 在一个可拖拽的卡片列表…

lazyvim恢复gt键

好的&#xff01;下面是一个完整的 LazyVim 键位配置 patch&#xff0c;将 gt / gT 恢复为 “切换标签页&#xff08;tab page&#xff09;” 的原始行为&#xff0c;同时保留原本 buffer 切换功能在其他键位上&#xff08;比如 / &#xff09;。 ⸻ ✅ 恢复 gt 为 Tab 切换&a…

React Native 在 Web 前端跨平台开发中的优势与实践

React Native 在 Web 前端跨平台开发中的优势与实践 对于广大 Web 前端开发者而言&#xff0c;移动端开发似乎总隔着一层“原生”的壁垒。学习 Swift/Kotlin、熟悉 Xcode/Android Studio 的高昂成本&#xff0c;让许多人望而却步。然而&#xff0c;“一次编写&#xff0c;多端运…

QT控件 使用QtServer系统服务实现搭建Aria2下载后台服务,并使用Http请求访问Json-RPC接口调用下载退出

前言 最近了解到qt-solutions这个开源项目,仔细研究一番&#xff0c;发现其中的QtServer项目能在Windows系统中创建系统服务&#xff0c;Linux/Unix系统中能作为守护进程使用&#xff0c;之前一直以为编写服务需要使用Windows api来实现&#xff0c;没想到这么简单。 本来之前就…

Python中关于数组的常见操作

Python中关于数组的常见操作 1.创建数组 array []2.添加元素 array.append()3.访问元素 print(array[2])通过索引进行数组元素的访问 4.修改元素 array[2] 3直接对想修改的元素位置进行赋值 5.删除元素 array.remove(2) #删除元素2del array[2] #删除索引为2的元素6…

Image 和 IMU 时间戳同步

1 目录 时间戳同步介绍 时间戳同步初探 时间戳获取方式 时间戳延迟估计方法 姿态补偿 匀速模型在 Bundle Adjustment 中的应用 重投影残差 视觉特征匀速运动补偿特征坐标 重投影残差 基于特征匀速模型算法的实验结果 轨迹匀速模型 vs 特征匀速模型 时间戳同步算法扩…

创建linux端口映射连接小网

&#x1f680; 方法 1&#xff1a;在执行机上配置 SSH 服务端转发 这个做法是在 执行机上配置一个常驻 SSH 隧道&#xff0c;把大网的某个端口长期转发到小网单板的 22 端口。 &#x1f468;‍&#x1f4bb; 操作步骤 1️⃣ 在执行机上创建一个 systemd 服务 假设&#xff1a; …

了解Java21

目前还没有实操过从java8/java11直接到java17,java21。 先储备下知识点&#xff0c;写一些简单例子&#xff0c;以便后续的实操。 一些新特性&#xff08;java8之后的&#xff09; var变量 和前端js定义变量一样了&#xff0c;var搞定public static void main(String[] args) {…

【代码】基于CUDA优化的RANSAC实时激光雷达点云地面分割

基于CUDA优化的RANSAC实时激光雷达点云地面分割 摘要&#xff1a; 本文介绍了一个高性能的激光雷达&#xff08;LiDAR&#xff09;地面分割项目。该项目基于RANSAC平面估计算法&#xff0c;并通过深度CUDA并行优化&#xff0c;将核心处理时间从近100ms缩短至10ms以内&#xff…

vuex原理以及实现

vuex官方文档 Vuex是什么&#xff1f; Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化 每一个 Vuex 应用的核心就是 store&#xff08;仓库&#xff09;。“stor…

APIs案例及知识点串讲(上)

一.轮播图专题CSS代码<style>* {box-sizing: border-box;}.slider {width: 560px;height: 400px;overflow: hidden;}.slider-wrapper {width: 100%;height: 320px;}.slider-wrapper img {width: 100%;height: 100%;display: block;}.slider-footer {height: 80px;backgro…

华大单片机HC32L110烧录程序方法

1&#xff0c;安装J-flash工具 从SEGGER官网下载J-flash工具&#xff0c;地址&#xff1a;SEGGER - The Embedded Experts - Downloads - J-Link / J-Trace。按向导安装完成。 2&#xff0c;使用如下图JLINK工具SWD模式连接单片机的烧录接口&#xff08;SWDIO,SWCLK,GND&#…