自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

侯仕奇的博客

葵花成海,你在不在

  • 博客(373)
  • 资源 (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 1237

原创 dSYM文件是什么 ?

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

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

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

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

2023-07-07 00:04:09 299

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

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

2023-07-05 00:05:02 168

原创 有哪些 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 585

原创 根据bundleID查询App信息

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

2023-04-04 17:46:12 1540

原创 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 699

原创 Category In Objective-C

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

2023-03-17 22:47:46 1135

原创 规并排序(Swift版本)

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

2023-03-06 00:15:26 523

原创 利用无缝桥接深入理解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 419

原创 怎样理解:source ~/.bash_profile

source ~/.bash_profile命令用于在当前终端会话中立即加载和执行~/.bash_profile文件中的配置,使环境变量、别名等即时生效而无需重启终端。关键点包括:source直接在当前Shell执行文件内容;~代表用户主目录;.bash_profile是Bash登录Shell的配置文件。典型用途包括刷新环境变量、加载旧配置到新Shell以及调试脚本。与之相关的还有.bashrc(交互Shell配置)和Zsh的对应文件。该命令搭配export和alias使用时,可快速更新PATH和命令别名。

2025-07-02 23:47:38 292

原创 解决 Cannot create Swift scratch context

摘要: Xcode调试时出现"无法创建Swift临时上下文(无法创建Clang导入器)"错误,通常是调试环境和工具链配置问题。主要原因包括:1) Xcode版本与调试器不匹配;2) Shell环境配置冲突;3) SDK路径或桥接头文件错误;4) 模块缓存损坏。快速解决方案:检查xcode-select路径是否指向正确Xcode版本;临时禁用Shell个性化配置;清理DerivedData和模块缓存;确保项目能单独编译;重装命令行工具。问题多由环境变量或工具链配置不当引起,建议先从干净环境

2025-07-02 23:08:49 761

原创 freezed_annotation,freezed 和 build_runner

freezed架构解析 freezed由两个包组成:freezed_annotation(主依赖,含注解)和freezed(开发依赖,代码生成器)。build_runner作为Dart官方的代码生成框架,协调构建流程。三者分工明确:注解标记需求,生成器实现逻辑,build_runner管理构建过程。这种架构类似Xcode的编译系统,兼顾灵活性与效率,是Flutter代码生成方案的典型设计。

2025-06-30 16:05:41 404

原创 pubspec.yaml 中的 dependencies 与 dev_dependencies

Flutter 项目中 dependencies 与 dev_dependencies 的核心区别在于: 用途不同:前者用于运行时依赖(如 http、shared_preferences),后者用于开发工具(如 build_runner、测试框架) 产物影响:dependencies 会打包进最终应用,dev_dependencies 不会 使用场景:运行期代码只能引用 dependencies,测试/构建脚本可引用 dev_dependencies 正确区分二者能有效控制应用体积、提高构建效率,并避免开发

2025-06-30 15:19:31 535

原创 Xcode 中的 Compilation Mode 是管什么的

Swift编译模式(Compilation Mode)是Xcode中控制编译范围的关键设置,包含Incremental(默认)、Whole Module和Automatic三种选项。其核心区别在于编译器处理文件的粒度:Incremental模式仅编译修改过的文件,适合Debug快速迭代;Whole Module模式全量编译整个模块,可实现跨文件优化,适合Release构建。开发者常因路径错误导致Incremental编译崩溃,此时切换模式可临时绕过问题(如帖子案例),但根本解决需修正头文件引用。实际开发中,

2025-06-29 18:05:03 782

原创 URL带有中文会引入哪些问题

Swift 中处理含中文字符 URL 的最佳实践 URL 标准规定只能使用 ASCII 字符,中文等 Unicode 字符需先转换。Swift 中直接使用中文 URL 会导致初始化失败(返回 nil)。本文总结了安全处理中文 URL 的方法: 核心问题:主机名自动转 Punycode,但路径/查询需手动百分号编码 解决方案: 使用 addingPercentEncoding 方法编码 推荐 URLComponents 自动处理编码 区分路径、查询等不同部分的编码字符集 常见陷阱:避免双重编码、正确处理查询参

2025-06-29 16:47:33 990

原创 Flutter 依赖注入神器 GetIt ~ 从 iOS 开发者视角深入理解

Flutter依赖注入框架GetIt实践指南 本文介绍了Flutter中流行的依赖注入框架GetIt的核心概念和实际应用。通过对比iOS开发中的依赖注入模式,详细解析了GetIt的注册方式(LazySingleton和Factory),展示了如何实现智能API切换机制和依赖链管理。文章还提供了具体使用示例、资源管理方法以及从iOS迁移到Flutter时的最佳实践建议,包括注册策略选择、模块化注入和测试支持。对于熟悉iOS依赖注入的开发者,GetIt提供了类似的容器管理功能,是Flutter项目中实现松耦合架

2025-06-28 23:30:09 531

原创 Swift × Android:官方工作组成立意味着什么?

Swift正式进军Android生态,成立Android Workgroup Swift语言生态迎来重大扩张,官方工作组宣布将Android打造为Swift的官方支持平台。这一举措将使Swift成为首个覆盖iOS/Android/Windows/Linux四大主流系统的全栈语言。工作组已启动CI测试、SDK打包和API适配等核心工作,目标实现Swift代码在Android平台的深度集成。 对开发者而言,此次扩展意味着: iOS业务逻辑可100%复用至Android Android开发者获得更现代的系统语言选

2025-06-28 13:17:56 1450

原创 Flutter 网络请求指南, 从 iOS 到 Flutter 的 Dio + Retrofit 组合

本文介绍了Flutter中强大的网络请求组合Dio+Retrofit,帮助iOS开发者快速上手。Dio作为HTTP客户端提供拦截器、请求转换等高级功能;Retrofit通过注解自动生成API接口代码,实现类型安全和代码简洁。文章详细讲解了Dio的基础使用、配置和拦截器,以及Retrofit的注解语法和代码生成方法,并提供了完整API服务示例。这种组合方式能显著提升Flutter项目中的网络请求开发效率和可维护性。

2025-06-27 23:48:52 855 3

原创 Cursor 对 flutter pub get 的误解

Flutter中flutter pub get与完整编译的区别:pub get仅负责依赖准备(解析版本、下载包、生成元数据),而不进行代码编译或打包。类比iOS开发,pub get类似pod install,而真正的编译(如flutter build)相当于Xcode的构建命令。pub get是编译的必要前提,但单独执行无法生成可运行的应用产物。完整编译流程还需包含Dart代码编译、平台代码构建和打包等步骤。

2025-06-27 19:08:33 278

原创 flutter pub get 深入解析,给 iOS 开发者看的 Flutter 依赖安装全流程

摘要:本文由侯仕奇撰写,详解Flutter依赖管理核心命令flutter pub get的工作原理。文章从iOS开发者的角度,将其类比为pod install,拆解了该命令执行的6个关键步骤(读取配置、版本求解、生成锁文件等),对比了与dart pub get、pub upgrade的区别,并解析了版本求解算法。通过对照CocoaPods体系,重点说明pubspec.lock和package_config.json双文件的协作机制,最后给出网络优化、离线构建等实战技巧。文章强调锁文件对团队协作的重要性,建议

2025-06-27 18:22:28 676

原创 Flutter 网络栈入门,Dio 与 Retrofit 全面指南

Flutter网络请求方案Dio+Retrofit全指南 本文针对iOS开发者介绍Flutter网络请求的最佳实践方案。Dio提供类似Alamofire的基础功能,包括全局配置、拦截器和任务管理,而Retrofit通过注解自动生成类型安全的API调用代码。两者的组合优势在于: 简化配置与拦截机制统一管理 自动JSON序列化/反序列化 支持并发请求、取消和进度监控 与iOS网络库的思维映射清晰 提供完善的扩展方案(Mock/缓存/重试等) 文末包含常见问题解决方案,帮助开发者快速适应Flutter网络开发范式

2025-06-27 17:53:28 1050

原创 Flutter ListTile 徽章宽度自适应的真正原因与最佳实践

Flutter会话列表未读消息徽章宽度自适应问题的解决方案:当徽章被放在ListTile的trailing属性中时,宽度会被父级Column拉伸导致无法自适应内容。本文揭示问题本质是由于Column强制拉伸徽章宽度,并提出优雅解决方案——对于多位数徽章,用Row(mainAxisSize: MainAxisSize.min)包裹Container,使宽度仅由内容和padding决定。最终实现单位数圆形、多位数胶囊形的自适应效果,并保持padding有效。该方案经实践验证,是解决Flutter未读徽章布局问题

2025-06-23 18:35:20 432

原创 Domain 层完全指南(面向 iOS 开发者)

本文介绍了在iOS开发中引入Domain层的重要性与实现方法。传统MVC/MVVM架构存在可测试性差、业务复用困难等问题,Domain层通过将业务概念模型(Entity/Value Object)与用例流程(Use Case)抽离为纯Swift代码,实现清晰的三层架构(Presentation-Domain-Data)。文章以聊天未读数功能为例,详细展示了Swift代码实现,包括Value Object验证、Repository协议定义、Use Case封装等。同时提供了单元测试策略和旧项目迁移步骤,强调D

2025-06-23 16:35:14 811

原创 Domain层到底是什么

Domain层是iOS应用架构中的业务核心层,包含业务实体、用例和仓库接口,采用纯Swift实现且不依赖任何框架。它独立于UI和数据层,使业务逻辑可测试、可复用。通过定义UseCase协议和实体对象,Domain层将业务规则与具体实现解耦,提升大型项目的可维护性。在现有项目中引入Domain层需逐步抽取业务逻辑、定义协议并重构UI,最终实现框架无关的核心业务模块。

2025-06-23 16:09:13 793

原创 深入解析 Flutter Bloc 在 AppBar 中的实战应用

本文介绍了Flutter中Bloc状态管理模式的应用实践。通过AppBar示例展示了如何用BlocBuilder和BlocListener分离UI与业务逻辑,分析了二者的使用场景与差异。文章还探讨了Bloc与Provider的协作方式,并总结了性能优化要点(如最小化重建范围、保持状态不可变等)和最佳实践(分层架构、批量更新等)。Bloc模式通过单向数据流使代码更可测、可维护,是构建健壮Flutter应用的有效方案。 (149字)

2025-06-23 15:57:05 979

原创 Flutter ListTile 深度解析

Flutter中的ListTile组件是构建Material Design列表界面的核心元素。该组件提供标准化的布局结构,包含leading(左侧内容)、title(主标题)、subtitle(副标题)和trailing(右侧内容)四个区域,并支持点击事件。ListTile遵循一致性、可读性和可交互性的设计原则,适用于聊天列表、设置页面等多种场景。开发者可以灵活定制样式,包括紧凑模式、背景色、边框形状等属性,并通过onTap和onLongPress实现交互功能。ListTile简化了列表项开发流程,同时确保

2025-06-20 23:27:30 600

原创 详细介绍 Provider 框架及其在 Flutter 中的使用方法

Provider是Flutter的状态管理框架,基于InheritedWidget简化状态管理。核心用法包括:1)通过ChangeNotifier创建可观察状态;2)用MultiProvider在应用根节点注册;3)使用Consumer/Selector局部监听状态变化,或通过Provider.of获取状态实例。Provider支持多状态组合和依赖注入,能有效管理应用全局状态,避免不必要的Widget重建。典型流程是先定义数据模型和ChangeNotifier,再在Widget树中通过上下文访问和修改状态。

2025-06-20 01:52:07 528

原创 理解 create 指向的箭头函数

本文解析了Flutter中ChangeNotifierProvider的create:参数用法。该参数接收一个匿名函数用于创建状态对象,在Provider首次插入widget tree时调用一次,对象会被缓存复用。关键点包括:匿名函数返回继承ChangeNotifier的状态对象;Provider自动管理生命周期,移出tree时调用dispose();所有操作都在主线程执行。与value:参数的区别在于,create:更适合新建对象并自动管理资源释放。总结来说,ChangeNotifierProvider通

2025-06-18 23:23:28 663

原创 ChangeNotifierProvider 本质上也是 Widget

Flutter中ChangeNotifierProvider本质上也是一个Widget,它继承自StatelessWidget并最终实现Widget抽象类,因此可以作为build方法的合法返回值。将其作为根节点可注入全局状态,通过context.watch在子树中访问,实现逻辑与UI的分离。这种设计遵循Flutter"组合Widget"的理念,在不修改UI结构的前提下提供状态管理能力。

2025-06-18 23:03:22 281

原创 iOS 开发者眼中的常量构造函数

本文解析了Flutter中const PaddedText({super.key})的语法组成及其作用。该声明使用Dart 2.17+的super.key语法糖自动传递key参数至父类,等效于传统手动转发写法。const构造函数使组件可被编译期实例化优化,{}表示可选命名参数。从Swift视角看,super.key类似自动生成的super.init调用,const则对应SwiftUI的静态视图优化。文中特别指出该语法需要Dart 2.17+支持,并强调key参数对Flutter组件识别的重要性。通过iOS开

2025-06-18 19:11:55 288

原创 为什么 所有 UI 操作必须在主线程?— 从框架设计到渲染流程的完整逻辑

UIKit和CoreAnimation框架不具备线程安全性,所有UI操作必须严格在主线程执行。主线程的RunLoop负责事件分发、布局计算和CoreAnimation事务提交,这一串行流程被绑定到特定的RunLoop阶段。多线程直接操作UI会破坏事务边界,导致数据竞争、渲染错乱甚至崩溃。正确做法是将耗时计算放在后台线程,最终UI更新通过DispatchQueue.main.async切回主线程执行,确保线程安全。违背主线程原则会导致不可预测行为,包括错位UI或程序崩溃。

2025-06-17 23:24:45 876

原创 理解 Data Race 与 Race Condition

Data Race两个或多个线程在没有同步机制的情况下,同时访问同一个变量,并且至少一个线程在写数据。(竞态条件)是指程序的正确性依赖于多个线程的执行顺序,而这个顺序是不可控的。它未必会导致崩溃,但会导致逻辑错误或状态异常。Data Race 是导致崩溃的“并发毒瘤”,而 Race Condition 是设计中的“逻辑地雷”。在日常 iOS 多线程开发中,保持警惕,对共享资源加锁,对状态流转做好保护,是避免这两类问题的根本办法。是否有多个线程访问同一个变量?

2025-06-17 10:00:00 517

原创 os_unfair_lock 的理解与使用

iOS 10引入的os_unfair_lock是Apple推荐的高性能轻量级锁,相比OSSpinLock解决了优先级反转问题,采用阻塞等待而非自旋机制。本文详细解析其原理、使用方法及性能优势,对比OSSpinLock和pthread_mutex,平均延迟降低30%以上。文章还提供Swift封装示例和最佳实践,强调其不可递归特性及正确释放锁的重要性。适用于高性能计数、资源池管理等场景,是线程安全同步的理想选择。

2025-06-16 23:42:06 602

原创 理解 Atomic 的局限性

getter 或 setter 调用能够“原子”地完成,也就是不会出现“撕裂读写”(torn read/write)或返回半更新状态;或者在新版 runtime 里,也可能用一把隐藏的 spin-lock(而非 @synchronized)来保护单次读/写。如果 didFailedRequest 可能在任何线程被调用, 怎样确保 Checking 过程的原子性?这样才能彻底杜绝在高并发场景下多个线程同时进入 Checking 流程的可能。:锁的粒度仅包裹在“单个属性存取”这一行代码里。

2025-06-16 23:25:06 982

原创 修改代码, 确保 Checking 过程在多线程下的原子性 (简体中文版)

如果 didFailedRequest 可能在任何线程被调用, 怎样确保 Checking 过程的原子性 ?在多线程环境下, 如果在任意线程被并发调用,那么下面这段代码就会出现竞态条件(race condition):两个线程 A、B 同时执行到 时,都可能看到 ,随后各自把它置为 YES,导致“Checking”流程被并发执行,破坏了原子性。最直观的方法,就是在检查和修改 时加锁。优点:语义清晰,容易理解; 性能优于 。缺点:如果“Checking”耗时较长,会频繁加锁解锁;锁的粒度、死锁等需

2025-06-15 17:59:55 423

原创 修改代码, 确保 Checking 过程在多线程下的原子性

本文探讨了Objective-C中处理nonatomic属性线程安全的四种方法:1)使用@synchronized或NSLock锁;2)串行调度队列;3)C11原子布尔操作;4)原子属性配合锁。每种方案各有优劣:锁操作简单但性能较差,串行队列高效但需管理多队列,原子操作性能最好但实现较复杂。文章特别强调,单独使用atomic属性无法保证复合操作(检查+设置)的原子性,必须配合同步机制。最后建议根据需求选择方案,简单场景用锁,高性能场景用队列或原子操作。文中还解释了相关技术术语如"撕裂读取&quot

2025-06-15 17:19:09 953

原创 鲜为人知的 Happy Eyeballs

Happy Eyeballs是一种优化双栈网络(IPv6/IPv4)连接速度的算法,旨在减少首包延迟并提升用户体验。其核心思想包括:1)并行获取IPv6和IPv4地址;2)交错排序地址;3)渐进式并发拨号(推荐250ms间隔);4)采用首个成功的连接并取消其他尝试。该算法解决了IPv6连接失败时传统顺序尝试导致的长时间等待问题。苹果系统(如NSURLSession)已原生支持Happy Eyeballs v2,开发者使用标准网络库即可自动受益。对于自定义实现,需注意地址排序、并发控制和连接取消等关键点。该技

2025-06-14 18:37:44 983

原创 在 iOS 开发中单独解析域名为 IP

驱动,iOS 15 起官方建议迁移到 Network.framework。—— 标准、安全、跨平台;若真要用 CFHost 必须接受弃用风险。:2025 年想在 iOS 上「开箱即用地拿到 IP」,首选依旧是。优缺点:自动回调、省去线程管理;但 API 已过时且。」不会把解析结果暴露出来,因此需要主动解析一步。

2025-06-14 00:31:24 505

原创 `dispatch_source_t` 计时器 vs `NSTimer`:核心差异一览

NSTimerMach 内核定时源leewayselfNSTimerleewaytolerance。

2025-06-11 23:16:18 804

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

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

2023-03-17

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

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

2016-07-25

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

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

2016-11-21

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

TA关注的人

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