自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

侯仕奇的博客

葵花成海,你在不在

  • 博客(333)
  • 资源 (2)
  • 问答 (7)
  • 收藏
  • 关注

原创 符号化的正确姿势

symbolicatecrash 是一个 exec (可执行文件), Xcode自带, iOS 15 之前的系统产生的 crash report, 可以直接被整个符号化, 文件路径可以通过。iOS 15 及之后的版本产生的 crash report, 格式有变, 已经无法使用 symbolicatecrash 符号化。使用条件: crash report 对应的 Archive 包是在本机构建的。将 .ips crash report 文件拖放到。中, 然后导出 .crash 符号化文件.

2023-07-10 01:13:25 1203

原创 dSYM文件是什么 ?

dSYM的全称是, 所以dSYM文件就是, dSYM文件中的每个 debug symbol, 对应了一个关系, 这个关系一端是源代码里真实的符号(类名称、全局变量以及方法和函数名称), 另一端则是其定义的文件号和行号.

2023-07-08 23:22:01 2981 4

原创 结束 guard else 只能使用 return ?

如果一个或者多个条件不成立,可用 guard 语句来退出当前作用域 (guard所在的作用域)。, guard所在的方法或者函数并不一定结束, 很多人没有意识到这一点!当 return 被执行, 程序只是退出。

2023-07-07 00:04:09 275

原创 当属性观察的对象是结构体

当 struct 中的某个属性被赋值, 会生成一个新的 struct 来替换旧的 struct, 新的 struct 包含新的属性?会响应 struct 属性的变化?因为 struct 是。

2023-07-05 00:05:02 160

原创 有哪些 shell 需要了解 ?

It combines features from both ksh and tcsh, offering functionality such as programmable command-line completion, extended file globbing (文件通配), improved variable/array handling, and themeable prompts (主题化提示).The shell’s name is an acronym (首字母缩拼词) for。

2023-04-09 17:52:00 566

原创 根据bundleID查询App信息

已知App的bundleID, 怎样查询应用信息.

2023-04-04 17:46:12 1471

原创 Swift的 ?? 运算符

Swift 中的??运算符, 官方称之为, 中文常被译作空合运算符在表达式a??b中, 将对可选类型 a 进行空判断,如果 a 包含一个值就进行解包,否则就返回一个默认值 b。表达式 a 必须是 Optional 类型。默认值 b 的类型必须要和 a 存储值的类型保持一致。// 无疑空合运算符(??)提供了一种更为优雅的方式去封装条件判断和解包两种行为,显得简洁以及更具可读性。a!= nil?a!: b注意如果 a 为非空值(non-nil),那么值 b 将不会被计算。这也就是所谓的短路求值。

2023-03-28 22:52:06 682

原创 Category In Objective-C

Category, 中文名: 分类, Objective-C 2.0中新增的语言特性

2023-03-17 22:47:46 1129

原创 规并排序(Swift版本)

时间复杂度为O(nlogn);适合大规模的数据排序;相比于冒泡排序、插入排序、选择排序这三种排序算法, 更加常用;用到了分治思想(即分而治之, 英文叫 “Divide and conquer”),非常巧妙;英文名称:Merge Sort;分治思想, 在很多领域都有广泛的应用,例如算法领域有分治算法(归并排序、快速排序都属于分治算法,二分法查找也是一种分治算法);分治算法一般都是用"递归"来实现的 (分治是一种解决问题的处理思想,递归是一种编程技巧);

2023-03-06 00:15:26 519

原创 利用无缝桥接深入理解Block的内部实现

深入理解Block的内部实现在Block内部访问外部变量//// main.m// SQIPlayground//// Created by 侯仕奇 on 2020/5/26.// Copyright © 2020 零下引力. All rights reserved.//#import <Foundation/Foundation.h>int main(int argc, const char * argv[]) { @autoreleasepool {

2020-05-27 10:06:45 415

原创 CBCharacteristic:是「特征」还是「数据通道」?

本文深入探讨了蓝牙低功耗(BLE)中的 Characteristic 概念,解释了其两种中文译法(“特征”和“数据通道”)的由来,并通过官方定义、开发者视角和乐高类比,帮助读者理解其核心作用。文章以智能手表为例,展示了 Characteristic 在实际应用中的表现形式,并通过 iOS 代码实战演示了如何发现、订阅、解析和写入 Characteristic 数据。最后,总结了设计协议和编写代码时的最佳实践,强调 Characteristic 作为 BLE 数据操作的核心单元的重要性。通过本文,读者可以更好

2025-05-20 23:57:07 839

原创 CoreBluetooth 入门:扫描并连接 BLE 手环实战

本文介绍了在iOS应用中使用CoreBluetooth框架进行BLE(低功耗蓝牙)开发的基本步骤和关键点。首先,文章解释了选择BLE的原因,包括其超低功耗、广播+连接双模式以及跨平台标准等优势。接着,详细说明了开发前的准备工作,如设置Xcode的Capability和Info.plist文件中的必要键值。文章还介绍了CoreBluetooth框架中的核心角色,包括CBCentralManager、CBPeripheral、CBService和CBCharacteristic,并强调了所有交互通过委托异步回调

2025-05-20 22:54:58 1056

原创 iOS 蓝牙开发中的 BT 与 BLE

在 iOS 开发中,BT(Bluetooth Classic) 和 BLE(Bluetooth Low Energy) 是两种不同的蓝牙技术,尽管它们源自同一蓝牙规范,但应用场景、协议栈和 API 支持存在显著差异。BT 主要用于高带宽、持续连接的应用,如音频传输和车载电话,iOS 仅对少数系统级 Profile 开放,开发者通常需要通过 ExternalAccessory 或 MFi 方案进行通信。而 BLE 则专为低功耗、间歇数据传输设计,如传感器和智能穿戴设备,iOS 从 iOS 5 起通过 Core

2025-05-19 23:40:43 1073

原创 理解 Swift 逃逸闭包与 implicit `self`

在 Swift 中,当一个闭包可能在其所在函数返回之后才被执行时,就称它为逃逸闭包你必须在参数类型前写@escaping// completion 可能在异步网络回调中被调用这是因为逃逸闭包会被某个对象持有,可能形成引用环或延迟释放;标注让编译器和开发者都能及早注意到内存管理风险。快速判断:如果闭包被存储到属性 / 变量里,或被异步 API(如 GCD、URLSession)保存后稍后执行——它就是逃逸的。逃逸闭包=离开原作用域后仍会执行的闭包,必须标记@escaping。**implicit。

2025-05-19 22:42:15 845

原创 理解 plank 自动生成的 copyWithBlock: 方法

Plank 生成的 PUGUser 类自带 copyWithBlock: 方法,用于在保持对象不可变的前提下进行局部修改。该方法通过创建 PUGUserBuilder,拷贝现有属性,允许用户通过 Block 修改特定字段,最终生成一个新的 PUGUser 实例。这种方法避免了直接修改原对象,确保了线程安全和状态的可预测性。相比手动创建 Builder 并设置属性,copyWithBlock: 语法更简洁,提高了代码可读性。它适用于需要局部更新模型并生成新实例的场景,如在 UI 层处理用户输入或同步数据时。P

2025-05-17 20:41:19 779

原创 在 LLDB 里看到的 “false” 究竟是什么?——一次指针真值与字符串布尔值的误会

在Objective-C中,user.mainland被误认为是布尔类型,实际上它是一个内容为@"false"的NSString常量指针。由于Objective-C的条件判断规则是只要指针非空就视为真,因此user.mainland在逻辑判断中始终为真,即使其内容为@"false"。这种类型错配通常发生在JSON到Model的自动映射过程中,后端将布尔字段序列化为字符串,而客户端直接映射为NSString属性。为了避免此类问题,应在模型层声明为BOOL或NSNumbe

2025-05-17 19:10:02 950

原创 一字典两世界:优雅移除 `NSDictionary` 指定键的最佳实践

在iOS开发中,当需要从不可变的NSDictionary中删除键值对时,直接操作会导致崩溃。原因在于字面量生成的字典是不可变的,且方法体内的self指针不可重新赋值。最佳实践是通过mutableCopy创建可变副本,删除指定键值对后再拷贝回不可变字典,并将新字典重新赋值给原变量。这种方法不仅线程安全,还能避免崩溃风险。社区惯例推荐将这一过程封装成分类,使调用方只需传入要删除的键,代码简洁易读。

2025-05-17 18:22:12 685

原创 理解为什么 try 必须由 do catch 包裹

trytry?try!并非“谁更好”的关系,而是为不同容错级别量身定制的工具。清晰评估失败的后果,再选择对应语法,才能写出既安全又简洁的 Swift 代码。希望本文能帮助你在 iOS 项目中合理使用错误处理,让潜在问题暴露在可控范围内,而非隐藏在 Bug 地雷中。祝编码愉快!

2025-05-13 19:20:09 433

原创 深入理解 iOS 开发中的 `use_frameworks!`

在 iOS 开发中使用 CocoaPods 管理依赖时,use_frameworks! 配置选项决定了第三方库是以动态框架(.framework)还是静态库(.a)的形式集成。动态框架的优势在于更好地支持 Swift 与 Objective-C 混合开发、提供模块化管理和便于独立更新依赖库,但其缺点是可能增加启动时间和应用体积。静态库则启动更快、体积更小,但难以实现模块化且对 Swift 支持不佳。开发者应根据项目需求选择是否启用 use_frameworks!:涉及 Swift 或混合开发时推荐使用动态框

2025-05-13 00:16:41 1237

原创 为什么不能给 https/http/file 注册 WKURLSchemeHandler?

将本文分享给团队,在 Code Review 中尽快剔除相关代码,避免未来线上崩溃与审核风险。新系统必崩,旧系统虽不崩但完全无效——线上“没有问题”只是因为运行在旧版本窗口。写给 iOS 开发者的原理解析 + 实测结果 + 迁移方案。

2025-05-10 00:06:16 766

原创 理解 WKWebView 的 handlesURLScheme: 方法:判断 URL 协议是否由 WebView 默认处理

方法用于检查给定的 URL 协议是否由WKWebView默认处理。这在处理网页请求时非常有用,尤其是在开发需要拦截或自定义 URL 请求的应用时。*/:这是一个NSString类型的参数,表示需要检查的 URL 协议。@return:返回一个布尔值,指示该 URL 协议是否被WKWebView默认处理。:此方法自 iOS 11.0 和 macOS 10.13 开始可用。

2025-05-08 18:19:47 826

原创 为什么根 CA 公钥固定几乎“白做”?

根证书固定仅限于限制受信任的根证书集,但操作系统通常已信任根证书,因此根证书固定只是重复操作系统默认的信任链。在 iOS 中,根证书是信任的锚点,验证根证书相当于复制默认信任,无法有效防止恶意攻击。攻击者若通过 DigiCert 获得伪造的证书,它还是会链到同一个根证书,从而绕过固定机制,因此根证书固定无法有效防范中间人攻击。根证书固定的风险在于,它无法有效防止中间人攻击(MITM),攻击者仍能伪造同一根证书下的合法子证书。更安全的方案是使用专用的中间证书 CA,减少根证书暴露的威胁。

2025-05-06 16:23:55 823

原创 什么是 CA?什么是 CA 证书?——一篇彻底搞懂 TLS 信任链

在 HTTPS/TLS 体系中,我们常听到CA根证书中间证书等概念。它们既相关又容易混淆。CA(Certificate Authority)= 实体/机构CA 证书(CA Certificate)= 证明该机构身份 & 公钥的数字证书术语自签名CA = TRUE预装系统主要职责根 CA 证书✓✓✓信任锚中间 CA 证书✗✓✗日常签发服务器证书✗✗✗证明网站身份一句话记忆CA 是人,CA 证书是人的身份证;

2025-05-05 22:53:49 621

原创 初识 iOS 开发中的证书固定

本文从“为什么要做证书固定”到“核心验证流程”,再到三种主流网络框架(原生、Alamofire、AFNetworking)的实战示例,帮助初学者系统掌握 iOS 证书固定的落地方案。做好 Certificate Pinning,为你的应用网络通信再添一道牢不可破的安全防线。扩展阅读苹果官方文档:Networking and Security → Secure Connections。

2025-05-04 20:23:54 624

原创 使用 DoH 查询域名 —— 以 core.tantanapp.com 为例的实战分析

在现代 iOS 应用中,为了确保 DNS 查询的隐私和完整性,我们可以使用来查询域名信息。本文将以type=A的含义响应中TTL的作用结果如何理解代码+注释逐行讲解插图帮助理解域名解析跳转流程type=A每条记录里都有一个TTL字段,比如67秒 或247秒。表示这条 DNS 记录在缓存中可以保存多久(单位:秒)。过期后客户端必须重新查询 DNS,获取最新的 IP 地址。📌 举例:如果TTL = 67,表示 67 秒内你都可以直接使用缓存 IP,不用再次请求 DNS 服务器。

2025-04-28 00:25:33 600

原创 深入理解 CNAME:iOS 开发者不能忽视的域名魔术

CNAME,全称 Canonical Name Record,标准中文叫做“规范名称记录”。把一个域名,指向另一个域名。而不是直接解析成 IP 地址。✅ 这样,当目标域名变化时,只需要修改被指向的域名,无需修改所有引用它的地方。很多 SaaS 平台(如 Firebase、AWS、Cloudflare CDN)都支持 CNAME 绑定。接入图片、音视频 CDN 加速使用 Push 推送服务(如 APNs Provider API)接入 WebSocket 通讯平台。

2025-04-27 17:50:36 1146

原创 什么是 SNI?iOS 开发者必懂的安全连接细节

SNI是的缩写,是 TLS 协议(HTTPS 加密层)的一项扩展。在 TLS 握手阶段,客户端主动告诉服务器:“我想访问的域名是 example.com”。这样,服务器就可以根据域名返回正确的证书,完成安全连接。在 iOS 网络开发中,只要连接目标是 IP 地址而非域名,你就必须手动设置 SNI,否则 TLS 握手会失败。SNI 是确保安全连接的重要一环,正确理解和使用它,是高级 iOS 网络开发者必须掌握的能力。自定义网络栈安全防护(防 DNS 劫持)iOS App 与服务器的高可用连接优化。

2025-04-27 02:03:46 375

原创 Network.framework 的引入,不是为了取代 URLSession

Network.framework 是为底层“连接、传输”设计的,不是直接用于发 HTTP 请求的,所以不会取代 URLSession。URLSession还是专门用来发送 HTTP/HTTPS 请求、管理 Cookie、处理 Redirect、自动缓存响应等。怎么建 TCP 连接,怎么做 UDP 传输,怎么监听端口,怎么管理 TLS 细节。自己实现自定义协议(比如 WebSocket)自己管理 IP 层的连接自己实现 DNS 解析 + TCP 握手 + TLS 验证。

2025-04-26 22:57:56 621

原创 详解 Network.framework:iOS 网络开发的新基石

是 Apple 提供的一套面向连接级别(Connection Level)编程的现代化 API。创建和管理 TCP / UDP 连接加密连接(TLS)多路径传输(Multipath TCP)网络状态实时监控(如 Wi-Fi/蜂窝网络切换)更安全的连接(默认支持 TLS 验证)✅ 更安全(默认启用 TLS)✅ 更高效(异步、低功耗优化)✅ 支持多路径(Multipath TCP)✅ 易用的 Swift 风格 API✅ 适配未来(如 QUIC、HTTP/3)

2025-04-26 22:09:53 1170

原创 什么是 DoH(DNS over HTTPS)?一文读懂 iOS 开发者眼中的安全 DNS 解析

在 iOS 网络开发中,我们常常依赖URLSession等库来发起网络请求,而这些请求背后第一步就是域名解析(DNS Resolution)。传统的 DNS 查询是明文的,这意味着它很容易被监听、篡改甚至劫持。而随着网络安全需求的提升,正式登上舞台,逐步成为更安全、更可靠的域名解析方式。本文将从 iOS 开发的视角,深入解析 DoH 的原理、优点、使用方式,以及在 App 中应用 DoH 的实践思路。

2025-04-25 01:27:06 1196

原创 当你在方法内部声明一个 block, 并在 5 秒后执行

—因为 Block 还没逃出栈帧。主角:局部栈 Block。

2025-04-23 20:35:26 561

原创 域名 → IP 的解析全过程

AFNetworking/URLSession/Alamofire 并不自己做 DNS。iOS 里真正把域名变成 IP 的,是 getaddrinfo()→ libsystem_dnssd → mDNSResponder → 外部 DNS 服务器这一条全局链路;只有理解这条链路,才能在安全、性能或可观测性上做针对性的优化。

2025-04-23 18:39:34 1124

原创 应该怎样理解“被劫持“

一句话:任何「未经应用或服务器授权,第三方改变了客户端—服务器之间解析结果、传输路径或数据内容」的情形,都视为网络被劫持。具体可拆成六大类类别典型表现触发信号1. TLS /MITM 劫持恶意中间人使用伪造证书重新加密流量证书/公钥与预埋值不符;TLS 版本被降级2. DNS 劫持域名解析被篡改,指向攻击者控制的 IP系统 DNS 与可信 DoH/DoT 解析结果不一致3. 代理注入网络设备静默加入显式/透明 HTTP(S) 代理;系统 Proxy 设置被修改4. 传输路径劫持。

2025-04-23 14:55:34 155

原创 iOS 中的虚拟内存 (理解为什么需要虚拟内存)

时,这些段会因为 ASLR 被整体“滑动”(加上 slide 值),但相对排列不变。的内存世界,也能让内核在背后高效地管理、隔离、复用有限的物理内存资源。借助虚拟地址空间,iOS 既能让每个 App 看到一个。,但实际上会被内核和硬件(MMU)动态翻译到真实。的一整块“虚拟地图”。

2025-04-21 11:21:00 1115

原创 Hello, Dirty page

因为 Dirty 页一定常驻 RAM,而 Clean 页随时可被回收。当一块虚拟页第一次被载入 RAM 时,它要么来自某个文件(Mach‑O 代码、PNG 资源等),要么是匿名零页(堆、栈、BSS)。它们在内存压力下可直接丢弃,下次缺页时再从闪存重读。,它才是真正决定你的 App 会不会被内存警告、会不会被 Jetsam 的硬指标。——磁盘里已有一份等价拷贝或可以重新生成。只读代码、图片、字符串常量等。时,MMU 会把页表里的。

2025-04-20 22:47:07 560

原创 000.初识 dyld

是 Apple 操作系统的动态加载器/链接器。自 iOS 15 起,Apple 改用。递归解析依赖的动态库(LC_LOAD_

2025-04-20 13:29:18 163

原创 Hi, 兄弟, SaaS 了解一下

*SaaS(Software as a Service,软件即服务)**是一种云计算交付模式:软件运行在服务商维护的云端基础设施中,通过 HTTP/HTTPS 接口向客户提供功能,用户只需登录浏览器、桌面客户端或移动 App 即可使用,而无须自行购买、部署或维护服务器、数据库、中间件和升级补丁。功能通过订阅计费(常见为月付 / 年付或按实际用量计费),开通后即可使用,停用后数据通常仍留存在服务商侧以便随时恢复。

2025-04-19 14:11:07 841

原创 didFinishLaunching 与「主线程首次 idle」, 哪个是更优的启动结束时间点 ?

更贴近用户真正“看到并可操作界面”的时刻,而误差仍可控制;同时埋点方案也比较稳健,可跨 UIKit / SwiftUI / SceneDelegate 使用。——系统即将把主线程睡眠,表明当前循环所有 Timer、Source、Layout、展示任务都完成了,首次出现通常紧跟在根 VC 的。更贴近用户实际体验,且仍保持实现简洁可维护,是多数 APM 场景更合理的。) 直接放到 Swift AppDelegate 中,逻辑完全一致。把 UI 绘制、布局、动画都算进启动耗时,比。的桥接版本,或直接使用。

2025-04-19 01:53:44 770

原创 iOS应用冷启动结束时间点的选择

iOS 冷启动”官方结束点是“第一帧成功绘制”;若想实现简易但相对准确的埋点,可退而求其次选 applicationDidBecomeActive:。

2025-04-19 01:43:28 688

原创 初识 Firebase 与 FPM

当然,随着业务成熟,建议密切关注用量和架构演进,必要时将热点服务迁移到更细粒度的云组件,以获得最佳的。它把实时数据库、托管、身份认证、云函数、分析与 A/B 实验等常用云能力封装成易用的 SDK,开发者几乎不用自建服务器就能快速上线、运维并持续迭代应用。对于追求持续交付与用户体验的移动 / Web 团队,FPM 和 Crashlytics 一起构成了 Firebase 的 APM 双核心,帮助你把“线上卡顿”变成可量化、可定位、可治理的指标体系。

2025-04-18 19:08:40 584

Objective-C, Category, 实现分析, 源代码

Objective-C, Category, 实现分析, 源代码

2023-03-17

分类中添加属性_实例代码

分类中添加属性_实例代码

2016-11-21

fgets( )和fputs( )(建议用其完全代替gets和puts函数)

很早之前,本人开始接触C语言的时候整理的笔记,包含了函数fgets( )和fputs( )的总结和使用心得,以及与对应的无f前缀函数的区别分析,现在分享给大家,仅代表个人观点,由于能力有限,难免有纰漏,仅供学习交流.

2016-07-25

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除