创建Objective-C可使用的Swift Framework

默认创建的使用Swift语言编写的framework是没有头文件的,如果另一个使用Objective-C语言编写的target想用引入swift framework,则需要在swift framework的工程上打开一些配置 同时使用public 和 @objc标记 要给Objective-C暴露swift编写的api,则需要使用public 和 @objc标记 @objc public class MySwiftClass: NSObject { @objc public func doSomething() { print("Doing something in Swift") } } 生成 Objective-C 兼容头文件 Swift Framework 的 Build Settings 中: Defines Module 设置为 YES。 Install Generated Header 设置为 YES。 这会生成一个 FrameworkName-Swift.h 头文件,包含 Swift 代码的 Objective-C 接口。 在 Objective-C 项目中导入导入 Swift Framework 的头文件 #import <FrameworkName/FrameworkName-Swift.h> MySwiftClass *swiftObject = [[MySwiftClass alloc] init]; [swiftObject doSomething];

September 24, 2025 · 1 min · holdsky

移动端环境,Kotlin Multiplatfrom 调用C/C++方法

前言 本文成文环境: macOS 26 Xcode 26 以及 iOS SDK Android Studio MeerKat Feature Drop 以及 Android SDK、NDK JDK 17 Gradle 8.11.1 Kotlin Multiplatfrom 通过Cinterop工具调用C/C++方法,也可以通过JNI规范调用C/C++方法。 本质上,都是调用C方法,C++方法需要通过 extern "C" 修饰为C方法。 本文将介绍Kotlin/Native在Android和iOS环境,如何调用C/C++方法。 Android Studio 推荐使用 Android Studio 开发Kotlin/Native (Kotlin更像是一款Android开发语言) Gradle Android Studio的御用构建工具(相比其构建工具,复杂且难用) CMake 一个事实上的C/C++构建标准工具,在Android和iOS环境调用各自平台的工具链构建C/C++。 创建 Kotlin Multiplatfrom 工程 如果Android Studio没有 Kotlin Multiplatfrom 工程模版,则需要先安装 Kotlin Multiplatfrom插件。 安装完成后,使用 Kotlin Multiplatfrom 工程模版创建一个工程(创建过程中,需要选择iOS的包管理方式,选择cocoapods) 镜像 因为环大陆的网络墙问题,可能需要配置下镜像仓库 1、找到工程根目录下的 settings.gradle.kts,添加下镜像仓库(下面配置的是阿里云的maven仓库) // settings.gradle.kts pluginManagement { repositories { maven{ setUrl("https://maven.aliyun.com/repository/public") } maven{ setUrl("https://maven.aliyun.com/repository/central") } maven{ setUrl("https://maven.aliyun.com/repository/gradle-plugin") } ... ... ... } } dependencyResolutionManagement { repositories { maven{ setUrl("https://maven.aliyun.com/repository/public") } maven{ setUrl("https://maven.aliyun.com/repository/central") } maven{ setUrl("https://maven.aliyun.com/repository/gradle-plugin") } ... ... ... } } 2、找到根目录下 gradle/wrapper/gradle-wrapper.properties,替换为distributionUrl ...

July 18, 2025 · 3 min · holdsky

CocoaPods Repo更新经常失败

先解决的墙的问题,建立高速且稳定的梯子,可以解决更新失败的问题。 还有一种原因是http协议导致的,切换到ssh协议成功率会更高。需要注意,使用ssh协议,需要有github账号,并配置好ssh 公钥信息。 使用ssh协议更新成功后,还要记得再将本地的cocoapods git仓库设置为http协议. cd ~/.cocoapods/repos/cocoapods // ssh git remote set-url origin https://github.com/CocoaPods/Specs.git // http git remote set-url origin git@github.com:CocoaPods/Specs.git 最后,首次初始化cocoapods repo仓库,也可以使用ssh协议 cd 一个临时文件夹 // 克隆到tmpRepo文件夹 git clone git@github.com:CocoaPods/Specs.git tmpRepo // 添加repo pod repo add trunk /xxx/yyy/tmpRepo // 修改远程地址 cd ~/.cocoapods/repos/cocoapods git remote set-url origin https://github.com/CocoaPods/Specs.git

November 1, 2024 · 1 min · holdsky

解析mach-o文件的依赖库列表,修改加载顺序

两个命令可以解决,otool和install_name_tool otool和install_name_tool # 显示依赖库列表 otool -L <mach-o文件路径> # 添加新的依赖库路径 install_name_tool -add_rpath <rpath> <mach-o文件路径> # 删除依赖库路径 install_name_tool -delete_rpath <rpath> <mach-o文件路径> # 替换依赖库路径 install_name_tool -change <old_rpath> <new_rpath> <mach-o文件路径> yololib 和ios App 对于iOS App,install_name_tool的-add_rpath、 -delete_rpath总是执行失败,需要借助yololib工具添加依赖 # 删除iOS App 的依赖 install_name_tool -change 需要删除的依赖 替换的空依赖 #变相实现删除 # 排序iOS App 的依赖 # 不断执行 install_name_tool -change ,实现排序

October 29, 2024 · 1 min · holdsky

【转】xcode: iOS 17.x not installed

运行命令,sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService 然后重启Xcode https://forums.developer.apple.com/forums/thread/751049

September 10, 2024 · 1 min · holdsky

为iOS构建libarchive

引用 libarchive源码 https://github.com/libarchive/libarchive/tree/v3.7.4 cmake工具手册 https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-ios-tvos-visionos-or-watchos 基本操作 需要安装cmake(brew install cmake) 然后使用cmake为libarchive配置xcode工程 cd 源码目录 cmake -S. -B_builds -GXcode -DCMAKE_SYSTEM_NAME=iOS #结果输出到_builds文件夹 一般会遇到以下错误 CMake Error at cat/CMakeLists.txt:33 (INSTALL): INSTALL TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE executable target "bsdcat". CMake Error at tar/CMakeLists.txt:46 (INSTALL): INSTALL TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE executable target "bsdtar". CMake Error at cpio/CMakeLists.txt:42 (INSTALL): INSTALL TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE executable target "bsdcpio". CMake Error at unzip/CMakeLists.txt:37 (INSTALL): INSTALL TARGETS given no BUNDLE DESTINATION for MACOSX_BUNDLE executable target "bsdunzip". 以上错误的原因是iOS App并不支持MACOSX_BUNDLE,在CMakeLists.txt中注释对应的INSTALL动作就可以了 ...

August 5, 2024 · 1 min · holdsky

知识蒸馏(大模型蒸馏)

本文内容来自 Llama-3-70B-T 的问答 知识蒸馏(Knowledge Distillation) 知识蒸馏(Knowledge Distillation)是一种模型压缩技术,旨在将大型模型(teacher model)的知识转移到小型模型(student model)中,以便小型模型可以学习到大型模型的特征表示和知识。 知识蒸馏的优点包括: 模型压缩:小型模型可以部署在资源有限的设备上,减少计算复杂度和存储空间需求。 提高性能:小型模型可以学习到大型模型的知识,提高其性能。 转移学习:知识蒸馏可以用于转移学习,例如将大型模型的知识转移到新的任务或数据集上。 知识蒸馏的应用包括: 模型部署:将大型模型部署在资源有限的设备上,例如移动设备或嵌入式系统。 模型压缩:压缩大型模型,以减少计算复杂度和存储空间需求。 转移学习:将大型模型的知识转移到新的任务或数据集上,以提高性能。 知识蒸馏的过程: 1. 训练教师模型(Teacher Model) 首先,需要训练一个大型的教师模型,该模型通常是一个复杂的神经网络,具有许多层和参数。教师模型需要在大量的数据上进行训练,以学习到丰富的特征表示。 2. 定义学生模型(Student Model) 其次,需要定义一个小型的学生模型,该模型通常是一个简单的神经网络,具有较少的层和参数。学生模型的目的是学习到教师模型的知识,并将其应用于实际问题中。 3. 蒸馏损失函数(Distillation Loss Function) 然后,需要定义一个蒸馏损失函数,该函数用于衡量学生模型和教师模型之间的差异。常见的蒸馏损失函数包括: KL 散度(Kullback-Leibler Divergence):衡量两个概率分布之间的差异。 MSE(Mean Squared Error):衡量两个模型的输出之间的差异。 4. 训练学生模型 接着,需要使用蒸馏损失函数来训练学生模型。训练过程中,学生模型需要学习到教师模型的知识,并将其应用于实际问题中。 5.soft目标(Soft Targets) 在训练学生模型时,通常使用soft目标来指导学生模型的学习。soft目标是教师模型的输出概率分布,经过softmax函数处理后的结果。soft目标可以帮助学生模型学习到教师模型的知识。 6.温度参数(Temperature Parameter) 在蒸馏损失函数中,通常引入一个温度参数(Temperature Parameter),该参数用于控制soft目标的softmax函数的温度。温度参数可以影响学生模型的学习过程。 7. 训练完成 最后,学生模型的训练完成后,可以将其应用于实际问题中。学生模型通常具有较小的计算复杂度和存储空间需求,因此可以部署在资源有限的设备上。 总的来说,知识蒸馏的过程是将教师模型的知识转移到学生模型中,以便学生模型可以学习到教师模型的特征表示和知识。 代码示意 import torch import torch.nn as nn import torch.optim as optim # Define the teacher model class TeacherModel(nn.Module): def __init__(self): super(TeacherModel, self).__init__() self.fc1 = nn.Linear(784, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): x = torch.relu(self.fc1(x)) x = self.fc2(x) return x # Define the student model class StudentModel(nn.Module): def __init__(self): super(StudentModel, self).__init__() self.fc1 = nn.Linear(784, 64) self.fc2 = nn.Linear(64, 10) def forward(self, x): x = torch.relu(self.fc1(x)) x = self.fc2(x) return x # Load the pre-trained teacher model teacher_model = TeacherModel() teacher_model.load_state_dict(torch.load('teacher_model.pth')) # Initialize the student model student_model = StudentModel() # Define the distillation loss function def distillation_loss(student_output, teacher_output, T): return nn.KLDivLoss()(nn.functional.log_softmax(student_output / T, dim=1), nn.functional.softmax(teacher_output / T, dim=1)) # Define the optimizer and temperature parameter optimizer = optim.Adam(student_model.parameters(), lr=0.001) T = 5.0 # Train the student model for epoch in range(10): for x, y in train_loader: # Forward pass teacher_output = teacher_model(x) student_output = student_model(x) # Calculate the distillation loss loss = distillation_loss(student_output, teacher_output, T) # Backward pass optimizer.zero_grad() loss.backward() optimizer.step() print(f'Epoch {epoch+1}, Loss: {loss.item()}') # Save the student model torch.save(student_model.state_dict(), 'tudent_model.pth')

May 30, 2024 · 2 min · holdsky

Ubuntu 从源码编译Python3

各个平台的安装过程请参考 安装依赖 // 更新系统 sudo apt-get update sudo apt-get upgrade // 安装依赖 sudo apt-get install -y make build-essential libssl-dev zlib1g-dev \ libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \ libncurses5-dev libncursesw5-dev xz-utils tk-dev 下载源码 // 需要自己确定对应版本的下载地址,下面连接是3.8.4版本 wget https://www.python.org/ftp/python/3.8.4/Python-3.8.4.tgz // 解压缩 tar xvf Python-3.8.4.tgz // 进入目录 cd Python-3.8.4 编译构建和安装 //配置环境 ./configure --enable-optimizations --with-ensurepip=install // -j 8标识 使用8个并行编译。量力而为,并行编译很是消耗资源 make //或者 make -j 8 // 安装到/usr/bin等目录(具体目录和版本有关) sudo make altinstall

April 12, 2024 · 1 min · holdsky

Ubuntn 重启后无网络连接

背景 租了一台服务器,某次重启后就无法连接网络了,多次重启后依然无网络连接,networking/network manager/ifdown/ifup都无法解决—-因为这台服器根本就没有安装这些命令/模块。 最终通过配置dhcpclient解决,解决过程参考了一篇博文( 原文看这里) 解决办法很简单,就是启动dhcpclient,并设置为开机自动启动。 确定网络接口名称 首先要确定连接互联网的接口名,通常是ens3。 可以使用 ifcconfig 命令获取 # 网络接口 ens3: ............... # 网络接口 lo是本地环回接口 lo: ................... 启动dhcpclient /sbin/ifconfig ens3 up # 启动ens3网卡 /sbin/dhclient ens3 # 分配ip地址 开机自动连接网络 创建服务文件 vi /etc/systemd/system/ens3-dhclient.service 文件内容如下 [Unit] Description=Enable ens33 network interface and start dhclient After=network.target [Service] Type=oneshot ExecStart=/sbin/ifconfig ens3 up ExecStart=/sbin/dhclient ens3 [Install] WantedBy=default.target 使服务文件生效 systemctl daemon-reload systemctl enable ens3-dhclient.service systemctl start ens3-dhclient.service

April 12, 2024 · 1 min · holdsky

iOS13 同一App实现多窗口(iPad和Vision平台)

在Info.plist中配置多窗口支持 Enable Multiple Windows 置为 YES 新建一个Scene配置(如果只有一个窗口,则不需要此操作) 判断当前环境是否支持多窗口 iOS13及以上支持多窗口;iPad设备和Vision设备支持,但iPhone不支持。 if (@available(iOS 13.0, *)) { if (UIApplication.sharedApplication.supportsMultipleScenes) {// Info.plist也配置了多窗口开关 if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad || UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomVision) { //支持多窗口 } } } 使用API创建新窗口 创建新的SceneDelegate 当App启用Scene后,需要使用Scene管理Window。为了管理新窗口,我们新建一个SceneDelegate @interface SecondSceneDelegate : UIResponder < UIWindowSceneDelegate ,NSUserActivityDelegate> @property (nonatomic,strong) UIWindow * window; @end @implementation SecondSceneDelegate // 将要连接到某个场景(Window需要依附在具体场景) - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { if (self.window == nil) { SecondSceneViewController *vc = [[SecondSceneViewController alloc] init]; // 自己定义的页面 UINavigationController *naviVc = [[UINavigationController alloc] initWithRootViewController:vc];//页面导航 self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.windowScene = (UIWindowScene *)scene; self.window.rootViewController = naviVc; [self.window makeKeyAndVisible]; } } @end 创建新窗口 使用 requestSceneSessionActivation ...

February 26, 2024 · 3 min · holdsky