创建静态库Static Library(Framework库原理相似)
在项目开发的过程中,经常使用静态库文件。例如两个公司之间业务交流,不可能把源代码都发送给另一个公司,这时候将私密内容打包成静态库,别人只能调用接口,而不能知道其中实现的细节。
简介:
库是一些没有main函数的程序代码集合。除了静态库,还有动态链接库,他们之间的区别是:静态库可以编译到我们的执行代码中,应用程序可以在没有静态库的环境中运行;动态库不能编译到我们的执行代码中,应用程序必须在有链接库文件的环境下运行。
创建静态库的步骤如下所示,
1、创建Static Library,新建->Project,选择Static Library,如图,
点击Next,我将Static Library项目名称命名为TimeDate,因为这是我用于处理时间和日期的静态库工程,
2、静态库文件功能的实现细节
创建了静态库Static Library项目之后,Xcode自动为我们创建了TimeDate.h/.m文件,如下图所示,
这时候我们需要在这里面填充一些细节,这里,我想要实现的功能就是将时间戳NSTimeInterval转换成NSString的功能,那么代码的细节如下所示,
TimeDate.h文件
@interface TimeDate : NSObject
- (NSString *)changeToStandardTime:(NSTimeInterval)timeInterval;
@end
TimeDate.m文件
#import "TimeDate.h"
@implementation TimeDate
- (NSString *)changeToStandardTime:(NSTimeInterval)timeInterval
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString *time = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:timeInterval]];
return time;
}
@end
上面的代码就是将NSTimeInterval转换成NSString,当然这样肯定有考虑不全面的地方,这不是本篇博客的中心内容,读者可以忽略;如果有好的建议请告诉我。
3、编译项目,生成对应的静态库.a文件
首先我们先来看一下编译(Command+B)之前的项目细节,如下图,
这里我们有两个细节需要注意的,①表明现在是选择的是名为pythonhater的真机Device;②libTimeDate.a文件是红色状态,表明这还不是一个实际存在的文件,我们不能在物理磁盘中找到它。只有在编译以后它才是一个实实在在的文件。
这时我们编译项目(Command+B),文件结构如下图,
这时候libTimeDate.a文件变为黑色状态了,表明编译过后它是一个真是存在于物理磁盘的文件,我们右键选择Show in Finder,如下图,出现了它的物理位置,
如图,libTimeDate.a文件隐藏的很深,我们只要知道它存在就好。现在有个问题,我选择的是pythonhater真机Device进行编译的,所以这个libTimeDate.a只能针对iOS真机Device进行使用,而不能在模拟器Simulator上面使用,为了解决这个问题,只要选择模拟器Simulator进行编译,就可以生成对应的模拟器运行需要的libTimeDate.a文件,如下图操作所示,
选择iPhone模拟器编译,然后右键Show in Finder,
上面的Debug-iPhones里面包含iPhone真机所需要的libTimeDate.a静态库文件,而下面的Debug-iPhoneSimulator里面包含的时iPhone模拟器所需要的libTimeDate.a静态库文件。
4、合并静态库
针对真机和模拟器的静态库文件只能在一个平台下面使用,好在我们可以将真机和模拟器上面的静态库文件合并成一个在真机和模拟器都可以使用的静态库文件,通过在终端输入命令即可完成该目的,
完整的命令就是:
lipo -create /Users/mini3/Library/Developer/Xcode/DerivedData/TimeDate-cthodjhjpplctjhfdbhmdcuhwnva/Build/Products/Debug-iphoneos/libTimeDate.a /Users/mini3/Library/Developer/Xcode/DerivedData/TimeDate-cthodjhjpplctjhfdbhmdcuhwnva/Build/Products/Debug-iphonesimulator/libTimeDate.a -output /Users/mini3/Desktop/libTimeDate.a
不过这个是相对自己的路径,读者可以直接将文件拖到终端即可识别完整的路径,如下图所示的方法,
最后在补充上- output /Users/用户名/Desktop/libTimeDate.a,这样就在桌面生成了一个合并过后的libTimeDate.a静态库文件,它可以再真机和模拟器上面同时使用。
5、使用静态库文件,
这时候我们就可以使用自己创建、编译生成的静态库文件了,将TimeDate.h文件和桌面上面的libTimeDate.a文件拖到想要使用的项目中,如下图的目录结构,
为了方便,我直接在AppDelegate中使用创建的静态库文件了,代码如下,
AppDelegate.m文件
#import "AppDelegate.h"
//导入头文件
#import "TimeDate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
TimeDate *timeDate = [[TimeDate alloc] init];
NSTimeInterval timeInterval = 123456798;
NSString *time = [timeDate changeToStandardTime:timeInterval];
NSLog(@"time is %@",time);
return YES;
}
输出的内容是,
2014-06-25 20:56:15.105 StaticLibrarySample[2517:390790] time is 1973-11-30 05:33:18
这时不管是真机还是模拟器都可以编译通过,正常运行。而使用者只能通过头文件知道我们提供的借口,却不知道实现文件中实现的细节,这有效地隐藏了自己的核心技术和机密内容。
总结:我们开发的就是iOS真机程序,所以可以选择不合并静态库,直接使用真机编译生成的静态库文件进行开发,没有必要为了兼容模拟器而合并静态库文件。当然,如果有强迫症或者公司设备不够,那么还是合并静态库文件吧。
感想:很早就想总结一下静态库的东西,但是感觉没有必要,也不知道怎么系统的总结。最近项目中,发现老大对于项目依赖关系处理的很牛逼,我很羡慕。如果我想达到他那样的水平,必须从头开始好好了解,而这第一步基本就是静态库方面的东西,所以必须走好第一步。这篇博客也算是我写项目依赖关系博客的前奏,后面我会更加深入的记录我自己对于项目管理方面的一些理解,希望对读者有所帮助。