http://www.jianshu.com/p/ef3d5b7e7006
http://www.knowsky.com/884469.html
http://www.jianshu.com/p/6c033c39884a
http://my.oschina.net/u/856930/blog/196484
http://ios.jobbole.com/81583/
https://segmentfault.com/q/1010000002952316
网上有很多解释和写法,这里根据自己的实测做一下综合
苹果平台的链接库除了静态库 .a 和 动态库.dylib 之外,Mac OS/iOS 平台还可以使用 Framework。Framework 实际上是一种打包方式,将库的二进制文件,头文件和有关的资源文件打包到一起,方便管理和分发,这样 Xcode 能够很容易的将其集成到你的工程中去。
在 iOS 8 之前,iOS 平台不支持使用动态 Framework,开发者可以使用的 Framework 只有苹果自家的 UIKit.Framework,Foundation.Framework 等。这种限制可能是出于安全的考虑。换一个角度讲,因为 iOS 应用都是运行在沙盒当中,不同的程序之间不能共享代码,同时动态下载代码又是被苹果明令禁止的,没办法发挥出动态库的优势,实际上动态库也就没有存在的必要了。
由于上面提到的限制,开发者想要在 iOS 平台共享代码,唯一的选择就是打包成静态库 .a 文件,同时附上头文件(例如微信的SDK)。但是这样的打包方式不够方便,使用时也比较麻烦,大家还是希望共享代码都能能像 Framework 一样,直接扔到工程里就可以用。于是人们想出了各种奇技淫巧去让 Xcode Build 出 iOS 可以使用的 Framework,Framework 还有 “伪”(Fake) Framework 和 “真“(Real) Framework 的区别。
iOS 8/Xcode 6 推出之后,iOS 平台添加了动态库的支持。为什么 iOS 8 要添加动态库的支持?唯一的理由大概就是 Extension 的出现。Extension 和 App 是两个分开的可执行文件,同时需要共享代码,这种情况下动态库的支持就是必不可少的了。但是这种动态 Framework 和系统的 UIKit.Framework 还是有很大区别。系统的 Framework 不需要拷贝到目标程序中,我们自己做出来的 Framework 哪怕是动态的,最后也还是要拷贝到 App 中(App 和 Extension 的 Bundle 是共享的),因此苹果又把这种 Framework 称为 Embedded Framework。
系统会在需要的时候将framework载入内存中,多个应用程序可以同时使用同一个framework。这种方法可以使得你的代码易分享,在多个工程中复用,并且可以隐藏实现细节,控制公开的头文件。
苹果平台的静态库和动态库的概念与其他平台的概念不尽相同。
总结来说:其实就是加载时机和加载次数的不同。
framework分为真机—Debug(调试)版本、真机—Release(发布)版本、模拟器—Debug版本、模拟器—Release版本;开发中一般都打包Release(发布)版本,将真机和模拟器版本合并,提供外界。(注意:debug和release要和引入framework的工程对应)
在项目开发的过程中,例如两个公司之间业务交流,不可能把源代码都发送给另一个公司,这时候将私密内容打包成framework,别人只能调用接口,而不能知道其中实现的细节。
选择左边那个framework,右边那个是创建.a静态库的。
在工程中创建类,写一些开放给外部用的接口。
第一个类,做点简单的加法,需要公开的api就写在h里面
//
// Compute.h
// FrameworkTest
//
// Created by yxhe on 16/7/6.
// Copyright © 2016年 yxhe. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Compute : NSObject
- (NSInteger)addNumber:(NSInteger)a withNumber:(NSInteger)b;
@end
//
// Compute.m
// FrameworkTest
//
// Created by yxhe on 16/7/6.
// Copyright © 2016年 yxhe. All rights reserved.
//
#import "Compute.h"
@implementation Compute
- (NSInteger)addNumber:(NSInteger)a withNumber:(NSInteger)b
{
return a + b;
}
@end
第二个类,打印
//
// Print.h
// FrameworkTest
//
// Created by yxhe on 16/7/6.
// Copyright © 2016年 yxhe. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Print : NSObject
- (void)printWords:(NSString *)words;
@end
//
// Print.m
// FrameworkTest
//
// Created by yxhe on 16/7/6.
// Copyright © 2016年 yxhe. All rights reserved.
//
#import "Print.h"
@implementation Print
- (void)printWords:(NSString *)words
{
NSLog(@"%@", words);
}
@end
最后在自动生成的导出头文件里把这两个类的h都import进去
//
// FrameworkTest.h
// FrameworkTest
//
// Created by yxhe on 16/7/6.
// Copyright © 2016年 yxhe. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for FrameworkTest.
FOUNDATION_EXPORT double FrameworkTestVersionNumber;
//! Project version string for FrameworkTest.
FOUNDATION_EXPORT const unsigned char FrameworkTestVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <FrameworkTest/PublicHeader.h>
#import <FrameworkTest/Compute.h>
#import <FrameworkTest/Print.h>
把需要公开调用的头文件一道public里面,需要隐藏的放在private里面。
生成成功后工程目录里的product从红色变成了正常颜色。
会看到分成了 模拟器和真机两个文件夹,此时就可以把这两个.framework分别引入到对应的模拟器或者真机项目使用了。
通过终端命令将两个framework合为一个模拟器和真机都可使用的framework。
打开控制台输入
lipo -create iphoneos下frameworkTest的路径 simulator下frameworkTest的路径 -output 新的路径,这样就完成了模拟器和真机版本的合并,新路径下的frameworkTest就是你合并后的文件,将这个文件名字改成和你未合并之前的Test一样的名字,放到framework文件夹下,替换掉原来的frameworkTest文件。
例如我的
lipo -create /Users/yxhe/Library/Developer/Xcode/DerivedData/FrameworkTest-gajdcpnghsabghalspugjmolohhd/Build/Products/Debug-iphoneos/FrameworkTest.framework/FrameworkTest /Users/yxhe/Library/Developer/Xcode/DerivedData/FrameworkTest-gajdcpnghsabghalspugjmolohhd/Build/Products/Debug-iphonesimulator/FrameworkTest.framework/FrameworkTest -output /Users/yxhe/Library/Developer/Xcode/DerivedData/FrameworkTest-gajdcpnghsabghalspugjmolohhd/Build/Products/FrameworkTest
在目标文件夹里找到那个FrameworkTest文件,拖到真机.framework文件夹里替换掉原来的,这样,真机.framework就可以当做universal的framework使用了。
1)选中项目名称
2)选中TARGETS
3)选中Build Phases
4)在Link Binary With Libraries中添加。
5)点击“+”号,加入所需的系统提供的.framework文件
6)引入头文件,就行了
这里主要使用之前创建的framework测试
1)从Finder里面直接将.framework文件直接拖到工程目录中
2)在Link Binary With Libraries中添加framework
其实一般拖进去之后,这个项系统自动添加了
注意:如果是Dynamic Libray形式的framework,需要添加到Embedded Frameworks
3)在项目中引入头文件即可
//
// ViewController.m
// FrameWorkUseTest
//
// Created by yxhe on 16/7/6.
// Copyright © 2016年 yxhe. All rights reserved.
//
#import "ViewController.h"
// 引入framework的头文件
#import <FrameworkTest/Compute.h>
#import <FrameworkTest/Print.h>
@interface ViewController ()
@end
@implementation ViewController
- (IBAction)onClick:(id)sender
{
Compute *compute = [[Compute alloc] init];
NSInteger sum = [compute addNumber:7 withNumber:5];
Print *print = [[Print alloc] init];
[print printWords:[NSString stringWithFormat:@"7 + 5 = %ld", (long)sum]];
_numberLabel.text = [NSString stringWithFormat:@"7 + 5 = %ld", (long)sum];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
csdn:diy的framwork
github:diy的framwork