Kyson - zjh171
type: channel
link: http://kyson.cn/index.php/author/1/
description: zjh171
items: 砸壳小记
items: libpag 源码解析
items: 一天开发一款小程序之BabyLoveRecord
items: 拆包达人系列（1）：直播类应用 Jaco
items: Flutter Engine iOS 调试指南
items: SRS 部署小记
items: 出来鞭尸了！ijkplayer iOS 编译完全指南（Xcode 26.0.1 下，修复部分问题）
items: windvane 容器原理揭秘
items: 微调大模型 all-MiniLM-L6-v2
items: 浅谈 iOS 下的多线程

砸壳小记
type: item
date: 2025-12-17T12:49:00+08:00
description: 前言砸壳网站 https://decrypt.day/ 广告太多，而且砸完的 APP 经常不能用。本文介绍如何使用flexdecrypt工具对iOS应用进行砸壳（解密），获取可用于逆向分析的IPA文件。注意Clutch 已经不能用了，现在一般使用 flexdecrypt 来砸壳。开始工具下载1. FlexdecryptGitHub仓库: https://github.com/JohnCoates/flexdecrypt直接下载:# 下载预编译版本 wget https://github.com/JohnCoates/flexdecrypt/releases/download/1.1/flexdecrypt.deb # 或下载二进制文件 wget https://github.com/JohnCoates/flexdecrypt/releases/download/1.1/flexdecrypt2. Flexdump辅助脚本Gist地址: https://gist.github.com/defparam/71d67ee738341559c35c684d659d40ac下载命令:curl -o flexdump https://gist.githubusercontent.com/defparam/71d67ee738341559c35c684d659d40ac/raw/flexdump3. 其他可选工具frida-ios-dump: https://github.com/AloneMonkey/frida-ios-dumpCrackerXI+: Cydia/Sileo商店安装安装步骤方法一：使用自动化脚本创建flexdecrypt_install.sh脚本：#!/bin/bash # 配置 IPHONE_IP="192.168.50.57" # 修改为你的iPhone IP IPHONE_USER="root" IPHONE_PASS="alpine" # 修改为你的root密码 # 下载flexdecrypt if [ ! -f flexdecrypt ]; then echo "Downloading flexdecrypt..." curl -L -o flexdecrypt https://github.com/JohnCoates/flexdecrypt/releases/download/1.1/flexdecrypt fi # 下载flexdump if [ ! -f flexdump ]; then echo "Downloading flexdump..." curl -o flexdump https://gist.githubusercontent.com/defparam/71d67ee738341559c35c684d659d40ac/raw/flexdump fi # 传输到iPhone echo "Transferring files to iPhone..." sshpass -p "$IPHONE_PASS" scp flexdecrypt root@$IPHONE_IP:/var/jb/usr/bin/ sshpass -p "$IPHONE_PASS" scp flexdump root@$IPHONE_IP:/var/jb/usr/bin/ # 设置权限 echo "Setting permissions..." sshpass -p "$IPHONE_PASS" ssh root@$IPHONE_IP "chmod +x /var/jb/usr/bin/flexdecrypt /var/jb/usr/bin/flexdump" # 创建符号链接（flexdump需要） sshpass -p "$IPHONE_PASS" ssh root@$IPHONE_IP "ln -sf /var/jb/usr/bin/flexdecrypt /var/jb/usr/bin/flexdecrypt2" echo "Installation complete!"方法二：手动安装连接到iPhone:ssh root@192.168.50.57 # 输入密码传输文件:# 在Mac上执行 scp flexdecrypt root@192.168.50.57:/var/jb/usr/bin/ scp flexdump root@192.168.50.57:/var/jb/usr/bin/设置权限:# 在iPhone上执行 chmod +x /var/jb/usr/bin/flexdecrypt chmod +x /var/jb/usr/bin/flexdump ln -s /var/jb/usr/bin/fle…

libpag 源码解析
type: item
date: 2025-12-16T16:11:00+08:00
description: 前言Jaco 中大量用到了 pag 动画，今天我们就来盘一盘 pag 的源代码。libpag 地址在这里。目录结构大概是这样： libpag/ ├── src/ # 核心源代码 ├── include/ # 公共 API 头文件 ├── third_party/ # 第三方依赖 ├── test/ # 测试代码和资源 ├── resources/ # 测试资源文件 ├── web/ # Web 平台实现 ├── ios/ # iOS 平台项目 ├── android/ # Android 平台项目 ├── mac/ # macOS 平台项目 ├── ohos/ # OpenHarmony 平台项目 ├── linux/ # Linux 平台支持 ├── win/ # Windows 平台项目 ├── viewer/ # PAG 查看器应用 ├── exporter/ # After Effects 导出器 ├── vendor/ # 供应商特定代码 ├── tgfx/ # TGFX 图形库（符号链接） ├── assets/ # 项目资源文件 └── .github/ # GitHub 配置 具体功能：src/base/作用: 基础数据结构和动画元素定义keyframes/: 关键帧动画系统，处理各种属性的时间插值 shapes/: 矢量形状定义（椭圆、矩形、路径、星形等） text/: 文本渲染相关（字体、段落、文字样式） effects/: 视觉效果（模糊、发光、阴影等 AE 效果） layerStyles/: 图层样式（描边、填充、渐变等） utils/: 基础工具类（数学运算、矩阵变换、颜色处理）src/codec/作用: PAG 文件格式编解码tags/: PAG 文件标签解析器，每个标签对应一种数据类型 mp4/: MP4 容器格式支持，用于视频预合成 utils/: 编解码工具（数据流读写、压缩解压）src/rendering/作用: 渲染引擎核心 layers/: 各种图层类型的渲染实现 ShapeLayer: 矢量形状图层 TextLayer: 文本图层 ImageLayer: 图片图层 SolidLayer: 纯色图层 PreComposeLayer: 预合成图层 filters/: GPU 滤镜和特效处理 video/: 视频解码和播放 sequences/: 序列帧管理 graphics/: 图形绘制基础设施 caches/: 渲染缓存系统（纹理、路径、字形缓存） drawables/: 可绘制对象抽象 editing/: 运行时编辑功能 renderers/: 不同渲染器实现 utils/: 渲染工具类 src/platform/作用: 平台特定实现android/: Android NDK/JNI 绑定，硬件解码器接口 ios/: iOS 框架集成，Metal/OpenGL 支持 mac/: macOS 特定功能，视频工具箱集成 cocoa/: iOS/macOS 共享的 Objective-C++ 代码 web/: WebAssembly 绑定，Canvas/WebGL 接口 win/: Windows 平台支持，DirectX/ANGLE 集成 ohos/: OpenHarmony 平台适配 linux/: Linux 平台基础支持 qt/: Qt 框架集成（跨平台 GUI） swiftshader/: 软件渲染器支持 源代码很难跑起来，我们要想使用他的话，还是下一个针对 iOS 的 demo。地址在这里：https://github.com/libpag/pag-ios开始iOS 项目一览运行 Demo 后，我们可以看到如下页面：可以看到他的功能比较强大，我们只需要一个 pag 文件，然后代码中加载即可。参考pag 官网

一天开发一款小程序之BabyLoveRecord
type: item
date: 2025-12-16T11:41:00+08:00
description: 编码小程序端直接使用 AI 编程，说出需求后，五分钟拿到效果图：大家想一起开发的，地址在这里：https://gitee.com/kysonkyson/heath_tracker 直接 提 merge request 即可。后端一样，使用 AI 编程，10 分钟出结果：发布前准备工作打包本地代码cd /Users/mac/projs/health_tracker/health-tracker-backend && mvn clean package -DskipTests 2>&1 | tail -20创建目录ssh root@120.92.216.96 "mkdir -p /opt/health-tracker && ls -ld /opt/health-tracker"上传包scp /Users/mac/projs/health_tracker/health-tracker-back end/target/health-tracker-backend-1.0.0.jar root@120.92.216.96:/opt/health-tracker/app.jar #Upload JAR to server服务端判断是否安装 Java，Mysql，Nginxssh root@120.92.216.96 "java -version 2>&1 | head -1; mysql --version 2>&1 | head -1; nginx -v 2>&1"MySQL 处理启动 Mysql：ssh root@120.92.216.96 "systemctl start mariadb && systemctl enable mariadb && systemctl status mariadb | grep Active"建表：ssh root@120.92.216.96 "mysql -uroot -e \"CREATE DATABASE IF NOT EXISTS health_tracker CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER IF NOT EXISTS 'health_user'@'localhost' IDENTIFIED BY 'Health@2025'; GRANT ALL PRIVILEGES ON health_tracker.* TO 'health_user'@'localhost'; FLUSH PRIVILEGES; SHOW DATABASES LIKE 'health%';\""GUI 工具查看可以使用 dbeaver 这款工具。官网在这里：https://dbeaver.io/，比较强大：Jar 包处理验证ssh root@120.92.216.96 "journalctl -u health-tracker -n 50 --no-pager" Check service logs确定 8081ssh root@120.92.216.96 "lsof -i:8081 | grep LISTEN || netstat -tlnp | grep 8081" Find process using port 8081杀掉之前的，启动新的：ssh root@120.92.216.96 "kill -9 81700 && sleep 2 && systemctl restart health-tracker && sleep 8 && systemctl status health-tracker | head -20" Kill old process and restart service启动服务ssh root@120.92.216.96 "systemctl daemon-reload && systemctl stop health-tracker && systemctl start health-tracker && systemctl enable health-tracker && sleep 5 && systemctl status health-tracker | head -15" Start health-tracker service配置 NginxCheckssh root@120.92.216.96 "ls -la /etc/nginx/conf.d/*.conf && cat /etc/nginx/conf.d/*.conf 2>/dev/null | head -50" Check existing Nginx configs配置 Nginxssh root@120.92.216.96…

拆包达人系列（1）：直播类应用 Jaco
type: item
date: 2025-12-12T16:50:03+08:00
description: 前言从今天开始，我们出一个系列叫做拆包达人：通过对 IPA 包的拆解，逆向的方式来学习，废话不多说，现在开始。Jaco中东直播应用，对标 TikTok 或者抖音，其 APP 长这样：拆完 IPA 包后，我们看到目录如下：. ├── _CodeSignature │ └── CodeResources ├── ai_generating.pag ├── ai_preparing.pag ├── AliVideoCert-com_weo_projectz-20240418175247.crt ├── AppAuthCore_Privacy.bundle │ ├── Info.plist │ └── PrivacyInfo.xcprivacy ├── AppsFlyerLib_Privacy.bundle │ ├── Info.plist │ └── PrivacyInfo.xcprivacy ├── ar.lproj │ ├── AppLocalizable.strings │ ├── InfoPlist.strings │ ├── JacoLocalizable.strings │ ├── LaunchScreen.strings │ ├── LiveLocalizable.strings │ ├── Localizable.strings │ ├── Main.strings │ ├── MessageLocalizable.strings │ ├── RongCloudKit.strings │ └── RongSticker.strings ├── Assets.car ├── AVPlayerPage.txt ├── Base.lproj │ ├── LaunchScreen.storyboardc │ └── Main.storyboardc ├── batter_full_like.json ├── batter_like_avatar.json ├── batter_like_heart.json ├── batter_like_soccer.json ├── BeetoADBundle.bundle │ ├── Assets.car │ ├── Info.plist │ └── zh-cn.lproj ├── big_playback_lottie.json ├── big_record_lottie.json ├── BMeiSheSDK.bundle │ ├── Info.plist │ └── meishe.lic ├── box_open.json ├── box_unclick.json ├── box_win.json ├── Bubble Tea.png ├── caption.bundle │ ├── 0C1A0ABB-3ECA-46B3-95C4-07555BBA3A5F.1.captionstyle │ ├── 0C1A0ABB-3ECA-46B3-95C4-07555BBA3A5F.lic │ ├── 0D4D1A68-5CE2-46E8-8635-7672EBA35FA2.1.captionstyle │ ├── 0D4D1A68-5CE2-46E8-8635-7672EBA35FA2.lic │ ├── 1C7EE477-20E9-494F-BF48-4D37E834A725.1.captionstyle │ ├── 1C7EE477-20E9-494F-BF48-4D37E834A725.lic │ ├── 1E61C62D-1317-4A5C-8773-830A19514735.1.captionstyle │ ├── 1E61C62D-1317-4A5C-8773-830A19514735.lic │ ├── 2044EE5C-D0B6-4E76-B6D5-391F0C4AD05E.1.captionstyle │ ├── 2044EE5C-D0B6-4E76-B6D5-391F0C4AD05E.lic │ ├── 24206D2B-F06E-4AA5-B4DF-5E103DF9DAB7.1.captionstyle │ ├── 24206D2B-F06E-4AA5-B4DF-5E103DF9DAB7.lic │ ├── 2C7609BE-7563-4E79-853D-B5540F593A11.1.captionstyle │ ├── 2C7609BE-7563-4E79-853D-B5540F593A11.lic │ ├── 2FE34C0F-F984-456F-8E2F-60EB1FEFEB90.9.captionstyle │ ├── 2FE34C0F-F984-456F-8…

Flutter Engine iOS 调试指南
type: item
date: 2025-12-06T22:41:00+08:00
description: 前言为何调试 Flutter Engine ？学习查 crash准备工作1. Flutter 版本Flutter 3.7.12 • Engine 1a65d409c7不一定是这个版本，但是你要记住你自己选择的版本，并找到对应的 dsym。2. 下载官方 iOS dSYM # 下载 (115 MB) curl -L -o Flutter.dSYM.zip \ "https://storage.googleapis.com/flutter_infra_release/flutter/1a65d409c7a1438a34d21b60bf30a6fd5db59314/ios-release/Flutter.dSYM.zip" # 解压 unzip -o -q Flutter.dSYM.zip3. UUID 验证dSYM UUID:x86_64 (Simulator): 4C4C4472-5555-3144-A169-E9E012AAE73B arm64 (Device): 4C4C4415-5555-3144-A112-3C0FFF4C00D2Engine Binary UUID:模拟器 (ios-arm64_x86_64-simulator):x86_64: 4C4C4472-5555-3144-A169-E9E012AAE73B ✅真机 (ios-arm64):arm64: 4C4C4415-5555-3144-A112-3C0FFF4C00D2 ✅完美匹配！模拟器和真机都能用！这一步搞定后，后面的就很 easy 了。步骤 1: 创建测试项目cd ~/projs/analyse_flutter_source flutter create ios_debug_demo --platforms=ios cd ios_debug_demo步骤 2: 配置 LLDB Source Mapping编辑 ~/.lldbinit（一次性配置）:# Flutter Engine 源码映射 settings set target.source-map /Users/runner/work/engine/src /Users/mac/flutter-engine/src步骤 3: 在 Xcode 中打开项目cd ~/projs/analyse_flutter_source/ios_debug_demo flutter build ios --release --simulator open ios/Runner.xcworkspace步骤 4: 配置 Xcode选择模拟器目标：Product → Destination → iPhone 15 Pro (或任意模拟器)配置 Scheme：Product → Scheme → Edit Scheme...Run → Info → Build Configuration: ReleaseRun → Options → ✅ Debug executable步骤 5: 添加 dSYM方法 1: 拖拽到 Xcode直接把 ~/projs/analyse_flutter_source/Flutter.dSYM 拖到 Xcode 的 Project Navigator方法 2: 命令行复制# 复制到项目构建目录 cp -R ~/projs/analyse_flutter_source/Flutter.dSYM \ ~/Library/Developer/Xcode/DerivedData/Runner-*/Build/Products/Release-iphonesimulator/步骤 6: 设置断点符号断点（iOS 工程师的最爱）:Debug → Breakpoints → Create Symbolic BreakpointSymbol: -[FlutterViewController viewDidLoad]Module: Flutter (可选，但推荐)最后看一下效果：

SRS 部署小记
type: item
date: 2025-12-06T22:28:00+08:00
description: 前言SRS 不用多介绍了，开干就行。一、安装 Docker# 安装 Docker sudo dnf install -y docker # 启动 Docker 服务 sudo systemctl start docker sudo systemctl enable docker # 验证安装 docker --version二、部署 SRS 流媒体服务器1. 拉取 SRS Docker 镜像docker pull ossrs/srs:52. 创建 SRS 配置文件mkdir -p /etc/srs cat > /etc/srs/srs.conf << 'EOF' listen 1935; max_connections 1000; daemon off; srs_log_tank console; http_server { enabled on; listen 8080; dir ./objs/nginx/html; } http_api { enabled on; listen 1985; } stats { network 0; } vhost __defaultVhost__ { # 直播优化配置 tcp_nodelay on; min_latency on; # 播放配置 play { gop_cache off; # 关闭 GOP 缓存，降低延迟 queue_length 10; # 播放队列长度 mw_latency 100; # 最小等待延迟 100ms } # HTTP-FLV 配置 http_remux { enabled on; mount [vhost]/[app]/[stream].flv; } # HLS 配置（可选） hls { enabled on; hls_path ./objs/nginx/html; hls_fragment 2; # 每个 TS 切片 2 秒 hls_window 10; # 保留 10 个切片 } } EOF3. 启动 SRS 容器docker run -d \ --name srs \ --restart always \ -p 1935:1935 \ -p 8080:8080 \ -p 1985:1985 \ -v /etc/srs/srs.conf:/usr/local/srs/conf/srs.conf \ ossrs/srs:54. 验证 SRS 运行状态# 查看容器日志 docker logs srs # 查看容器状态 docker ps | grep srs # 访问 Web 管理界面 # http://服务器IP:8080三、测试推流需要先安装 ffmpeg，没有的，来我这里看一下。1. 推流测试（彩条 + 实时时间）ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \ -f lavfi -i sine=frequency=1000:sample_rate=44100 \ -vf "drawtext=fontsize=60:fontcolor=white:box=1:boxcolor=black@0.7:x=(w-text_w)/2:y=(h-text_h)/2:text='%{localtime}'" \ -c:v libx264 -pix_fmt yuv420p -preset ultrafast -tune zerolatency \ -profile:v baseline -g 60 -b:v 800k \ -c:a aac -b:a 128k \ -f flv rtmp://127.0.0.1:1935/live/test2. 验证流状态# 检查流参数 ffprobe -v error -show_streams http://127.0.0.1:8080/live/test.flv # 应该看到： # codec_name=h264 # width=1280 # height=720 # pix_fmt=yuv420p3. 播放测试VLC 播放器：打开网络流：http://服务器IP:8080/live/test.flv

出来鞭尸了！ijkplayer iOS 编译完全指南（Xcode 26.0.1 下，修复部分问题）
type: item
date: 2025-12-02T16:26:00+08:00
description: 前言“GitHub 上的 ijkplayer 是‘尸体’，B站内部的 ijkplayer 是‘活体’。”那么，鞭尸有何帮助？老项目应该还有一些在维护，需要做一些适配的时候，我能提供一些帮助新人想上手直播拉流的，可以参考一下本文档。概述macOS 上为 iOS 平台如何编译 ijkplayer ？此文为您解答ijkplayer 是基于 FFmpeg 的轻量级 Android/iOS 视频播放器，具有以下特点：支持 iOS/Android 平台基于 FFmpeg n4.0 版本支持硬件加速解码支持直播流播放 (RTMP, HLS)可定制化的编解码器支持编译结果总览成功编译的架构 | 架构 | 目标平台 | SDK | 库文件大小 | 编译时间 | |-----|---------|-----|-----------|---------| | **arm64** | iOS 真机 | iPhoneOS | ~25 MB | ~8分钟 | | **x86_64** | iOS 模拟器 | iPhoneSimulator | ~31 MB | ~8分钟 | | **Universal** | 通用库 | 合并 | ~56 MB | ~1分钟 | 生成的库文件build/universal/lib/ ├── libavcodec.a (37.6 MB) - 编解码器核心库 ├── libavfilter.a (1.4 MB) - 音视频过滤器库 ├── libavformat.a (10.9 MB) - 封装格式处理库 ├── libavutil.a (3.0 MB) - 工具函数库 ├── libswresample.a (696 KB) - 音频重采样库 └── libswscale.a (4.3 MB) - 视频缩放库环境要求与配置系统要求macOS版本: 10.15+ (Catalina 或更高)Xcode版本: 14.0+ (本次使用 26.0.1)磁盘空间: 至少 5GB 可用空间内存: 建议 8GB+必需工具# 安装 Homebrew (如果未安装) /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # 安装必需工具 brew install yasm # 汇编器 brew install pkg-config # 包配置工具 (可选) brew install nasm # 另一个汇编器 (可选) # 验证 Xcode 命令行工具 xcode-select --install xcode-select -p环境变量配置# 添加到 ~/.zshrc 或 ~/.bash_profile export PATH="/usr/local/bin:$PATH" export DEVELOPER_DIR=$(xcode-select -p)项目初始化与配置修改1. 克隆项目git clone https://github.com/bilibili/ijkplayer.git ijkplayer-ios cd ijkplayer-ios git checkout -B latest k0.8.82. 初始化 iOS 构建环境./init-ios.sh这个脚本会：下载 gas-preprocessor (ARM 汇编预处理器)拉取 FFmpeg 源代码为每个架构创建 FFmpeg 分支设置配置文件链接3. 关键配置修改3.1 架构配置 (compile-ffmpeg.sh)# 只使用现代架构 FF_ALL_ARCHS_MODERN="arm64 x86_64" FF_ALL_ARCHS=$FF_ALL_ARCHS_MODERN3.2 Xcode 26+ 兼容性修复 (tools/do-compile-ffmpeg.sh)移除废弃的 Bitcode 标志:# arm64 架构 elif [ "$FF_ARCH" = "arm64" ]; then FF_XCODE_BITCODE="" # 原来是 "-fembed-bitcode" # x86_64 架构 elif [ "$FF_ARCH" = "x86_64" ]; then FF_XCODE_BITCODE="" # 原来是 "-fembed-bitcode"更新最低 iOS 版本:# arm64 FF_XCRUN_OSVERSION="-miphoneos-version-min=12.0" # x86_64 FF_XCRUN_OSVERSION="-mios-simulator-version-min=12.0"添加编译器兼容性标志:FFMP…

windvane 容器原理揭秘
type: item
date: 2025-12-01T13:18:00+08:00
description: 前言阿里内部使用的 windvane 容器原理剖析抛出问题端上设计缺陷问题处理（iOS首页白屏，Bridge 调用卡顿）统一两端方案安全加固性能优化（加载速度过慢）双端感知（H5 内部跳转（非原生跳转） 情况下 端上如何感知）H5 沉浸式页面（如全屏视频、游戏、直播）解决！时间线--------------------------------------------------------- | WindVane架构演进 | --------------------------------------------------------- | 年份/阶段 | 2013-2014 | 2015 | now | --------------------------------------------------------- | 交互时 | Hybrid API| | | | | 平台化 | | | --------------------------------------------------------- | 下载时 | | 预加载 | | | | | HTTP-DNS | | | | | SPDY | | --------------------------------------------------------- | 渲染时 | | | 渲染 | ---------------------------------------------------------前期主要处理交互问题，后期开始处理下载问题以及渲染问题。首页白屏问题分两步app 第一次进入 wk 会白屏，解决方案：适当时机（比如进入骑手个人中心页面后）就启动一个空白 wkwebview。统一两端方案这个不用说，web 负责渲染 UI，逻辑部分通过 Javascript 各自端上实现。我们分开来看web 页面渲染只需要 Html + CSS（当然，部分 UI 展示需要借助一定的 JS 逻辑）Javascript 通过 Web 容器提供的通道来实现双向通信安全加固三个方案：参数校验（Schema Validation）参数不对则拒绝来源校验（Origin Check）不是 饿了么 host， 则拒绝防重放攻击每次 invoke 带唯一 nonce + 时间戳；服务端校验防止重复提交。性能优化（加载速度过慢）离线包。静态资源（js、html、css）本地加载即可。亮点WindVane 采用 “预注入 + 动态增强” 双阶段注入策略，在页面加载前完成基础能力注入，运行时按需注入业务 SDK。流程图：阶段一：预注入 核心 js时机：WKWebView 初始化后、loadRequest 之前注入的内容：window.WindVanePromise 风格的 invoke(method, params) 方法__callbacks 映射表基础事件监听（如 onPageReady）注意为什么必须在 loadRequest 前注入？确保 H5 页面第一行 JS 就能调用 Bridge，避免“Bridge not ready”错误。阶段 2：动态注入业务 SDK（按需）时机：收到 H5 的特定信号（如 ）方式：从本地缓存或 CDN 下载 login_sdk.js通过 evaluateJavaScript 注入优势：减少首屏 JS 体积按业务域隔离能力（防滥用）数据：淘宝早期因 Bridge 未就绪导致的 JS 错误率 >15%，注入前置后降至 <0.1%。保证跨平台一致性：前端无需写 if (isIOS) ... else if (isAndroid) ...。双端感知监听 History API：WindVane 会注入 JS 代码，劫持 pushState / replaceState：const originalPush = history.pushState; history.pushState = function() { originalPush.apply(history, arguments); // 通知原生：页面已跳转 windvane.notifyPageChange(location.href); };H5 沉浸式页面什么是“沉浸式”？页面需要 隐藏状态栏、导航栏可能要求 横屏锁定用户手势（如下滑）可能触发 退出全屏 而非返回上一页原生 UI（如 ActionBar）需动态隐藏/显示WindVane 如何处理？扩展 JSBridge API提供类似：// H5 主动请求沉浸式 windvane.setImmersiveMode({ immersive: true, orientation: 'landscape', hideNavBar: true }…

微调大模型 all-MiniLM-L6-v2
type: item
date: 2025-11-26T17:54:00+08:00
description: 前言最近在开发一款 Flutter 学习 APP，主要通过用户提问的方式学习 Flutter，为了确保用户的隐私以及回复的效率，我打算自己实现一个本地模型，供 AI 助手调用，UI 已经写的七七八八了：开始

浅谈 iOS 下的多线程
type: item
date: 2025-11-21T12:38:00+08:00
description: 前言直接上干货┌─────────────────┬─────────────────┬─────────────────┬─────────────────┐ │ 场景特征 │ 推荐方案 │ 原因 │ 示例 │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ 读多写少 │ Barrier │ 读取并发性能好 │ 弹幕、评论 │ │ 高并发读取 │ │ 写入一致性保证 │ 股票行情 │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ 读写均衡 │ Serial Queue │ 实现简单 │ 配置管理 │ │ 低并发 │ │ 无死锁风险 │ 用户设置 │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ iOS 13+ │ Actor │ 现代安全 │ 新项目 │ │ 新项目 │ │ 编译时检查 │ SwiftUI应用 │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ 极致性能 │ 读写锁 │ 接近无锁性能 │ 高频交易 │ │ 系统级开发 │ (pthread) │ 精细控制 │ 数据库引擎 │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ 简单场景 │ Lock │ 实现简单 │ 单线程访问 │ │ 低并发访问 │ │ 强一致性 │ 启动配置 │ └─────────────────┴─────────────────┴─────────────────┴─────────────────┘对比各个方案┌─────────────────┬─────────────────┬─────────────────┬─────────────────┐ │ 工具 │ 现实类比 │ 核心功能 │ 适用场景 │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ 串行队列 │ 单行道 │ 任务排队执行 │ 简单顺序执行 │ │ (Serial Queue) │ (一次一辆车) │ │ │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ Barrier │ 收费站 │ 读写分离 │ 读多写少 │ │ │ (多入口单出口) │ │ │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ 锁 (Lock) │ 单间厕所 │ 完全互斥 │ 强一致性 │ │ │ (一次一个人) │ │ │ ├─────────────────┼─────────────────┼─────────────────┼─────────────────┤ │ 信号量 │ 停车场 │ 控制并发数量 │ 资源池限制 │ │ (Semaphore) │ (有限车位) │ │ │ └─────────────────┴─────────────────┴─────────────────┴─────────────────┘barrierBarrier 最适合的经典场景：缓存系统：图片缓存、API响应缓存状态管理：购物车、用户配置、游戏状态网络数据：实时数据同步、WebSocket消息UI组件：主题管理、数据源、配置持久化：日志系统、数据库连接池协作应用：实时编辑、多用户状态 Barrier 的本质是读写锁的实现，图形化表示 Barrier 状态机： ┌─────────┐ 开始读取 ┌─────────┐ 最后一个读者完成 ┌─────────┐ │ 空闲 │ ──────────> │ 读取中 │ ──────────────> │ 空闲 │ │ (Idle) │ │(Reading)│ │ (Idle) │ └─────────┘ └─────────┘ └─────────┘ ^ │ │ │ Barrier完成 │ 请求Barrier │ └──────────────────────┘ │ ┌─────────┐ │ │Barrier │ <─────…