从framework里面读资源文件

来源:互联网 发布:正品篮球鞋淘宝店铺 编辑:程序博客网 时间:2024/06/09 23:18
  • 以前的.a静态库是不能包含资源文件的。所以毫无疑问,如果需要xib, img等资源文件的话,需要打包在.bundle中,和.a一起发布,一般保持两者同样的名字。

  • 从iOS8开始,可以用framework,并且可以包含资源文件,可以放弃.bundle文件了。这主要是从使用方便的角度来讲的。将代码和资源分离,完成同一功能要找两个地方,自找麻烦。

  • 在framework中开发,就像跟主程序中开发一样,按照功能分模块,划分文件夹。将同一功能的文件都放在一个文件夹中,包括Storyboard,xib,image,Code等等,以最短路径获取所需要的信息。

  • 将framework和bundle分两个隔离是不合理的,同样,在framework中包含一个bundle同样也是不合理的。模块间隔离的单位是framework,在framework内部,应该考虑充分共享以及获取的方便性,再引入第二级的bundle,只能是自我设限,得不偿失。让.bundle和.a成为历史,全面使用framework。

  • 还有一种情况,就是当资源的体积很大的时候,比如视频、地图之类的。这种时候,将资源单独放在一个bundle中,与程序分离,可以不同时间发布,也不用重新发版本,有一定的意义。不过,对于大资源,直接以文件的形式下载就可以了,有必要用bundle多包一层吗?

  • 除了主程序,其他framework的地位都是平等的,不存在framework之中包含framework的概念。取而代之的,是依赖关系。所以,整体架构在物理上就两层,主程序和framework。逻辑上的层次和包含等概念,都要理解依赖。比如要开发一个Network.framwork,需要用到AFNetworking.framework。在逻辑上是主程序-》Network.framwork-》AFNetworking.framework。但是在物理上的关系是
    主程序-》Network.framwork和主程序-》AFNetworking.framework。AFNetworking.framework与Network.framwork地位是完全平等的,只不过想用Network.framwork的程序必须同时将AFNetworking.framework包含进来。

  • 可以把framework想象为主程序中的一个文件夹。在没有framework的主程序中,资源是直接放在根目录下的。但是,引入了framework之后,就像把资源移动了相应的子目录。这样路径就发生了变化,NSBundle这个类就是为了区分这种变化。

在framework里面读framwork自己的资源文件

这是framework内部的资源,跟其他都没有关系。但是framework不能单独存在,必须要放在某个“主程序”中才能起作用。bundle参数如果不传,那么默认是mainBundle,这种情况路径就不对了。这种情况下,可以用下面这个API来获得bundle参数。

+ (NSBundle *)bundleForClass:(Class)aClass;
    // 获取bundle参数    NSBundle *bundle = [NSBundle bundleForClass:self.class];    // 读UIStoryboard    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@“StoryboardName” bundle:bundle];    // 读UIImage    UIImage *image = [UIImage imageNamed:@"icon_back_gray" inBundle:bundle compatibleWithTraitCollection:nil];    // 文件路径    NSString* htmlPath = [bundle pathForResource:@"index" ofType:@"html"];

在主程序中读framework里面的资源文件

同样也是利用bundle参数来读取,class选择framework中某个导出的class就可以了。

    // 获取bundle参数,ZAFinanceFrameworkManager是framework中接口类    NSBundle *bundle = [NSBundle bundleForClass:[ZAFinanceFrameworkManager class]];

在framework中读主程序的资源文件

这个和在主程序中读自己的一样,不需要bundle参数,一定要传的话,就传nil或者[NSBundle mainBundle]

从framework里面读其他framwork里面的资源文件

同样也是利用bundle参数来读取,class选择目标framework中某个导出的class就可以了。

小结

在单体程序中,NSBundle这个参数不需要管,全部传nil或者是默认的[NSBundle mainBundle]就可以了。

引入了framework之后,就需要NSBundle这个参数来区分资源所在的模块。确定NSBundle比较简单的方法是用下面这个API,其中的class只要选择资源所在的framework中的某个class就可以了。如果是Swift,并且不是类类型,那么就可以用“self.dynamicType”来取得类型。

+ (NSBundle *)bundleForClass:(Class)aClass;

关于模块划分的原则

苹果的指导原则是MVC,在大多数情况是合适的,客户端都比较小,几个页面跳转一下,加几个动画就差不多了。
近来,随着移动设备性能的提升,手机越来越像电脑了,手机客户端也越来越重,慢慢地跟PC端客户端一样。
程序变大了,为了便于维护,就要想办法划分模块,PC端经历过的事情很快就在手机端重演。
从iOS8开始,苹果提供了动态链接库framework,这个就相当于PC端的dll。手机客户端的组件化、平台化也像在PC端那么方便了。



参照 http://www.jianshu.com/p/3549984315bf
2 0