iOS静态库(.a)及资源文件的生成与使用详解(OC版本)
引言

iOS静态库(.a)及资源文件的生成与使用详解(Swift版本)_xcode 合并 .a文件-CSDN博客
在前面的博客中我们已经介绍了关于iOS静态库的生成步骤以及关于资源文件的处理,在本篇博客中我们将会以Objective-C为基础语言,深入探讨如何在项目中有效地生成和集成静态库,特别是包含了资源文件的静态库。这种方法可以帮助开发者在多个项目中重用代码与资源,大大提高开发效率和项目模块化的灵活性。接下来,我们将一步步解析从创建静态库到添加资源文件、配置Build Settings、测试集成效果等关键步骤。
准备代码
我们仍然以创建一个通用的Toast组件为例,它将包含图片和文字,并暴漏一个公共的方法来供其它类调用,来显示我们创建的Toast提示。
我们需要一个PHToastView来构建我们的Toast视图,代码就不进行过多解释了。
PHToastView.h中的接口如下:
#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface PHToastView : UIView/// 显示toast
/// @param text toast内容
- (void)showToast:(NSString *)text;@endNS_ASSUME_NONNULL_END
PHToastView.m的具体实现如下:
#import "PHToastView.h"@interface PHToastView ()/// 图标
@property(nonatomic,strong)UIImageView * iconImageView;
/// 文字
@property(nonatomic,strong)UILabel * textLabel;@end@implementation PHToastView- (instancetype)initWithFrame:(CGRect)frame {if (self = [super initWithFrame:frame]) {[self setupUI];}return self;
}- (void)setupUI {self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];self.layer.cornerRadius = 5;self.layer.masksToBounds = YES;// 图标[self addSubview:self.iconImageView];self.iconImageView.frame = CGRectMake(10.0, 1.0, 14.0, 14.0);//读取名称PHToast.bundle中的图片NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"PHToast" ofType:@"bundle"]];NSString *path = [bundle pathForResource:@"toast_loading" ofType:@"png"];self.iconImageView.image = [UIImage imageWithContentsOfFile:path];// 文字[self addSubview:self.textLabel];self.textLabel.textColor = [UIColor whiteColor];self.textLabel.font = [UIFont systemFontOfSize:14];
}/// 显示toast
/// @param text toast内容
- (void)showToast:(NSString *)text {self.textLabel.text = text;[self.textLabel sizeToFit];self.textLabel.frame = CGRectMake(29.0, 0.0, self.textLabel.frame.size.width, 16.0);self.frame = CGRectMake(0, 0, self.textLabel.frame.size.width + 39.0, 16.0);
}- (UIImageView *)iconImageView {if (!_iconImageView) {_iconImageView = [[UIImageView alloc] init];}return _iconImageView;
}- (UILabel *)textLabel {if (!_textLabel) {_textLabel = [[UILabel alloc] init];}return _textLabel;
}@end
另外还需要一个PHToastHelper类来管理Toast的显示工作。
PHToastHelper.h中的接口如下:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface PHToastHelper : NSObject/// 创建单利
///
/// @return 单利对象
+ (instancetype)sharedInstance;/// 显示toast
/// @param text toast内容
/// @param view toast显示的view
- (void)showToast:(NSString *)text withView:(UIView *)view;@endNS_ASSUME_NONNULL_END
PHToastHelper.m的实现如下:
#import "PHToastHelper.h"
#import "PHToastView.h"@interface PHToastHelper ()/// 是否已经显示
@property(nonatomic,assign)BOOL isShow;@end@implementation PHToastHelper/// 创建单利
+ (instancetype)sharedInstance {static PHToastHelper * instance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[PHToastHelper alloc] init];});return instance;
}/// 显示toast
/// @param text toast内容
/// @param view toast显示的view
- (void)showToast:(NSString *)text withView:(UIView *)view {if (self.isShow) {return;}self.isShow = YES;PHToastView * toastView = [[PHToastView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];[toastView showToast:text];toastView.frame = CGRectMake(0, 0, toastView.frame.size.width, 16.0);toastView.center = view.center;[view addSubview:toastView];dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{[toastView removeFromSuperview];self.isShow = NO;});
}@end
构建.a静态库
准备好代码之后,接下来我们开始将这些代码封装成一个.a静态文件,来供其它模块使用。
和Swift中的静态库构建步骤相同。
1. 首先我们来创建一个Static Library静态库。
- 点击Xcode菜单栏“File” -> “New” -> “Project”。
- 在弹框中选择Framework & Library下的“Static Library”。
- 新创建的Static Library项目结构中,会有两个默认的文件。



2. 修改最低支持版本,及支持架构。
- 在General目录下修改最低支持版本(Minimum Deployments)。
- 在Build Settings下面选择静态库所支持的架构,如果是用于真机我们选择arm64,模拟器选择x86_64(M系列的芯片,直接选择arm64)。


3. 导入文件,并选择对外暴漏文件。
- 将我们已经构建好的Toast代码导入到静态库中。
- 在Build Phases目录下打开“Copy Files”,选择PHToastHelper.h文件,之后在生成静态库时,Xcode会自动为我们拷贝一份该文件到include目录。


4.构建并导出.a文件及头文件。
- 运行代码直到Xcode显示Build Success,表示静态库构建成功。
- 点击菜单栏的“Product” -> “Show Builder Folder in Finder”在Products文件夹中找到生成的.a文件,以及include文件。


构建资源包.bundle文件
构建资源包的步骤和Swift版本并没有什么区别,在这里我们再简单的重复一下步骤。
- 新建一个 Bundle target:在Xcode中,选择 “File” -> “New” -> “Target”,然后选择“macOS”(即使是iOS项目,.bundle文件也使用),在选择“Bundle”选项,输入资源包名称。
- 将资源文件添加到Bundle target:把需要的资源(图片、音频、配置文件等)拖入到Xcode中,然后在“Target Membership”中选择刚创建的.bundle文件。
- 确保在新创建的Bundle target中的Build Settings中的“Skip Install”选项设置为YES,防止它被打入最终的App。
- 运行新建的Bundle Target,成功之后文件将会生成在项目“Products”目录下。
使用.a及.bundle文件
接下来我们将.a文件include文件夹中的头文件以及.bundle文件,同时导入到项目当中,引入头文件就可以使用刚刚构建的Toast功能了。
- 引入.a文件,头文件以及.bundle文件。
- 添加代码调用Toast功能。

#import "ViewController.h"
#import "PHToastHelper.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];button.frame = CGRectMake(100, 100, 100, 50);[button setTitle:@"showToast" forState:UIControlStateNormal];[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[button addTarget:self action:@selector(showToast) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:button];}- (void)showToast {[[PHToastHelper sharedInstance] showToast:@"这是一个toast" withView:self.view];
}@end
效果如下:

结语
通过本篇博客的介绍,我们了解了如何在OC项目中生成并集成包含资源文件的静态库.a。相对于Swift的静态库,OC中需要自行设置对外开放文件,这一点需要注意。
静态库的使用不仅能让代码复用更高效,同时也有助于项目结构的清晰和模块化的实现。在实际开发中,掌握这种方式可以帮助我们更灵活地管理资源,提高代码的可维护性和移植性。希望本篇内容能够为大家提供一个实用的开发思路,在后续的项目中更好地应用静态库的特性。
相关文章:
iOS静态库(.a)及资源文件的生成与使用详解(OC版本)
引言 iOS静态库(.a)及资源文件的生成与使用详解(Swift版本)_xcode 合并 .a文件-CSDN博客 在前面的博客中我们已经介绍了关于iOS静态库的生成步骤以及关于资源文件的处理,在本篇博客中我们将会以Objective-C为基础语言…...
Python自动化:关键词密度分析与搜索引擎优化
在数字营销领域,搜索引擎优化(SEO)是提升网站可见性和吸引有机流量的关键。关键词密度分析作为SEO的一个重要组成部分,可以帮助我们理解特定关键词在网页内容中的分布情况,从而优化网页内容以提高搜索引擎排名。本文将…...
苏州金龙新V系客车创新引领旅游出行未来
10月25日,为期三天的“2024第六届旅游出行大会”在风景秀丽的云南省丽江市落下帷幕。本次大会由中国旅游车船协会主办,全面展示了中国旅游出行行业最新发展动态和发展成就,为旅游行业带来全新发展动力。 在大会期间,备受瞩目的展车…...
linux:DNS服务
DNS简介: DNS系统使用的是网络的查询,那么自然需要有监听的port。DNS使用的是53端口, 在/etc/services(搜索domain)这个文件中能看到。通常DNS是以UDP这个较快速的数据传输协议来查 询的,但是没有查询到完…...
传奇架设好后创建不了行会,开区时点创建行会没反应的解决办法
传奇架设好后,测试了版本,发现行会创建不了,按道理说一般的版本在创建行会这里不会出错的,因为这是引擎自带的功能。 建立不了行会虽然说问题不大,但也不小,会严重影响玩家的游戏体验,玩游戏为的…...
【小白学机器学习28】 统计学脉络+ 总体+ 随机抽样方法
目录 参考书,学习书 0 统计学知识大致脉络 1 个体---抽样---整体 1.1 关于个体---抽样---整体,这个三段式关系 1.2 要明白,自然界的整体/母体是不可能被全部认识的 1.2.1 不要较真,如果是人为定义的一个整体,是可…...
安全研究 | 不同编程语言中 IP 地址分类的不一致性
作为一名安全研究人员,我分析了不同编程语言中 IP 地址分类 的行为。最近,我注意到一些有趣的不一致性,特别是在循环地址和私有 IP 地址的处理上。在这篇文章中,我将分享我对此问题的观察和见解。 设置 我检查了多种编程语言&am…...
小小的表盘还能玩出这么多花样?华为手表这次细节真的拉满
没想到小小的表盘还能玩出这么多花样?华为这次细节真的拉满!还有没有你不知道的神奇玩法? 情绪萌宠,心情状态抬腕可见 好心情就像生活馈赠的糖果,好的心情让我们遇到困难也不惧打击!HUAWEI WATCH GT 5情绪…...
trueNas 24.10 docker配置文件daemon.json无法修改(重启被覆盖)解决方案
前言 最近听说truenas的24.10版本开放docker容器解决方案放弃了原来难用的k3s,感觉非常巴适,就研究了一下,首先遇到无法迁移老系统应用问题比较好解决,使用sudo登录ssh临时修改daemon.json重启docker后进行docker start 容器即可…...
数字孪生,概念、应用与未来展望
随着科技的飞速发展,数字化已经成为各行各业的发展趋势,在这个过程中,数字孪生作为一种新兴的技术,逐渐引起了人们的关注,本文将对数字孪生的概念、应用以及未来展望进行详细介绍。 数字孪生的概念: 数字孪…...
Chromium HTML Input 类型Text 对应c++
一、文本域(Text Fields) 文本域通过 <input type"text"> 标签来设定,当用户要在表单中键入字母、数字等内容时,就会用到文本域。 <!DOCTYPE html> <html> <head> <meta charset"ut…...
SpringMvc参数传递
首先对于post请求汉字乱码需要进行过滤器配置 普通参数传递 直接传递 客户端传递的属性名与我的bean中的函数参数名相同 映射传递RequestParam("XXX") 在我们方法参数中定义一个与客户端属性名一致 并绑定参数 POJO实体类传递 嵌套POJO传递 数组likes参数传递…...
西安国际数字影像产业园:数字化建设赋能产业升级与拓展
西安国际数字影像产业园的数字化建设,在当前经济与科技迅猛发展的大背景下,已然成为提升园区管理效率、服务水平以及运营效果的关键趋势。随着信息技术日新月异的进步,数字化更是成为这座产业园转型升级的核心关键词。如今,西安国…...
linux线程池
线程池: * 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用࿰…...
PyTorch图像分类实战——基于ResNet18的RAF-DB情感识别(附完整代码和结果图)
PyTorch图像分类实战——基于ResNet18的RAF-DB情感识别(附完整代码和结果图) 关于作者 作者:小白熊 作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测…...
【OccNeRF: Advancing 3D Occupancy Prediction in LiDAR-Free Environments】阅读笔记
【OccNeRF: Advancing 3D Occupancy Prediction in LiDAR-Free Environments】阅读笔记 1. 论文概述Abstract1. Introduction2. Related work2.1 3D Occupancy Prediction2.2 Neural Radiance Fields2.3 Self-supervised Depth Estimation 3. Method3.1 Parameterized Occupanc…...
DDRPHY数字IC后端设计实现系列专题之后端设计导入,IO Ring设计
本章详细分析和论述了 LPDDR3 物理层接口模块的布图和布局规划的设计和实 现过程,包括设计环境的建立,布图规划包括模块尺寸的确定,IO 单元、宏单元以及 特殊单元的摆放。由于布图规划中的电源规划环节较为重要, 影响芯片的布线资…...
EDA --软件开发之路
之前一直在一家做数据处理的公司,从事c开发,公司业务稳定,项目有忙有闲,时而看下c,数据库,linux相关书籍,后面跳槽到了家eda公司,开始了一段eda开发之路。 eda 是 electric design …...
51c~目标检测~合集2
我自己的原文哦~ https://blog.51cto.com/whaosoft/12377509 一、总结 这里概述了基于深度学习的目标检测器的最新发展。同时,还提供了目标检测任务的基准数据集和评估指标的简要概述,以及在识别任务中使用的一些高性能基础架构,其还涵盖了…...
计算机低能儿从0刷leetcode | 33.搜索旋转排列数组
题目:33. 搜索旋转排序数组 思路:看到时间复杂度要求是O(log N)很容易想到二分查找,普通的二分查找我们已经掌握,本题中的数组可以看作由两个分别升序的数组拼成,在完全升序的部分中进行二分查找是容易的,…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
